1. 程式人生 > >【GYM102091】2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest

【GYM102091】2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest

房子 選擇 hid 技術 stdout 表示 class lar min

A-Evolution Game

題目大意:有$n$個不同的野獸,定義第$i$ 個野獸有 $i$ 個眼睛和 $h[i]$ 個角,你可以任意從中選擇一個野獸進行進化,每次進化角數量必須增加,而且進化後要滿足眼鏡的變化量 $\triangle i \leq w$,求最多的進化次數。

題解:以$h$的值從大到小排序,$f[i]$表示從第i個野獸開始進化的最多次數。對於$1 \leq i \leq j$若滿足條件則$f[j]=max \{ f[i]+1 \}$。

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4
#include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 9 int n,w,ans; 10 int f[5005]; 11 struct hh 12 { 13 int eye,horn; 14 }a[5005]; 15 bool cmp(hh a,hh b) 16 { 17 return a.horn>b.horn; 18 } 19 int main() 20 { 21 int i,j;;
22 scanf("%d%d",&n,&w); 23 for(i=1;i<=n;i++) 24 scanf("%d",&a[i].horn); 25 for(i=1;i<=n;i++) 26 a[i].eye=i; 27 sort(a+1,a+1+n,cmp); 28 for(i=1;i<=n;i++) 29 for(j=i+1;j<=n;j++)//h[i]>h[j] 30 if(a[i].horn>a[j].horn&&abs(a[i].eye-a[j].eye)<=w)
31 f[j]=max(f[j],f[i]+1); 32 for(i=1;i<=n;i++) 33 ans=max(f[i],ans); 34 printf("%d",ans); 35 return 0; 36 }
View Code

D-Bus Stop

題目大意:給出$n$個房子的坐標,要建立公交車站使得每個房子離最近的車站不過10公裏,求最少的車站數。

題解:從左往右貪心即可。

技術分享圖片
#include <bits/stdc++.h>
using namespace std;
const int N=3e6;
int m,n;
int a[N];
int ans,lstop;
int main()
{
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        lstop=a[1]+10;
        ans=1;
        for(int i=2;i<=n;i++){
            if(abs(a[i]-lstop)<=10){
                ;
            }
            else{
                lstop=a[i]+10;
                ans++;
            }
        }
        if(n==0)ans=0;
        if(n==1)ans=1;
        printf("%d\n",ans);
    }
}
View Code

G-Communication

題目大意:求有向圖強連通分量數。

題解:Floyed+並查集或者Tarjan。

技術分享圖片
#include <bits/stdc++.h>
using namespace std;
const int N=1e3;
int m,n,c,ans,a,b;
int f[N];
int edge[N][N];
int fnd(int x)
{
    if(f[x]==x)return x;
    return f[x]=fnd(f[x]);
}
int main()
{
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d%d",&n,&c);
        memset(edge,0,sizeof(edge));
        for(int i=0;i<n;i++)
            f[i]=i;
        for(int i=1;i<=c;i++){
            scanf("%d%d",&a,&b);
            edge[a][b]=1;
        }
        for(int k=0;k<n;k++)
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++){
                    if(edge[i][k]&&edge[k][j])edge[i][j]=1;
                }
        ans=0;
        for(int i=0;i<n-1;i++)
            for(int j=i+1;j<n;j++){
                if(edge[i][j]+edge[j][i]==2){
                    f[j]=fnd(i);
                }
            }
        for(int i=0;i<n;i++){
            if(f[i]==i)ans++;
        }
        printf("%d\n",ans);
    }
}
View Code

H-As rich as Crassus

題目大意:$x^3 \equiv A_i \ \ (mod \ \ N_i) (i=3)$,求$x$。

題解:中國剩余定理

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n,t;
long long ans;
long long b[15],m[15];
long long exgcd(long long a,long long b,long long &x,long long &y){
    if(b==0){x=1,y=0;return a;}
    long long d=exgcd(b,a%b,x,y);
    long long z=x;x=y,y=z-a/b*y;
    return d;
}
void print(long long x){
    if(!x) return;
    if(x) print(x/10);
    putchar(x%10+0);
}
int main()
{
    int i;
    long long x,y,M,aa,bb,cc,d,tmp;
    bool flag;n=3;
    scanf("%d",&t);
    while(t--)
    {
        ans=flag=0;
        for(i=1;i<=n;i++)
            scanf("%I64d",&m[i]);
        for(i=1;i<=n;i++)
            scanf("%I64d",&b[i]);
        M=m[1],ans=b[1];
        for(i=2;i<=n;i++)
        {
            aa=M,bb=m[i],cc=(b[i]-ans%bb+bb)%bb;
            x=0,y=0;
            d=exgcd(aa,bb,x,y);
            bb=bb/d;
            if(cc%d){flag=1;break;}
            x=((x*cc/d)%bb+bb)%bb;
            ans+=M*x;M*=bb;
            ans=(ans%M+M)%M;
        }
        if(flag)puts("-1");
        else {
            if(!ans)puts("0");
            else
            {
                tmp=pow(ans,1.0/3.0);
                if(tmp*tmp*tmp<ans) printf("%I64d\n",tmp+1);
                else printf("%I64d",tmp);
            }
        }            
    }
    return 0;
}
close
View Code

J-Floating-Point Hazard

題目大意:給出L,R,求$\sum_{i=L}^{R}(\sqrt[3]{i+10^{-15}}-\sqrt[3]{i})$。

題解:微分

技術分享圖片
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    #endif // LOCAL
    int a,b;
    while(~scanf("%d%d",&a,&b)){
        if(!a||!b) break;
        double ans=0;
        for(ll i=a;i<=b;i++){
            ans+=pow(i*i,-1/3.0);
        }
        ans*=1.0/3*(1e-15);
        printf("%.5E\n",ans);
    }
}
View Code

K-The Stream of Corning 2

題目大意:給出若幹個數和存在的時間點,問某一時刻存在的數中的第k大。

題解:將一個操作的起始點和終止點拆開標記,按時間排序後,用樹狀數組+二分求動態第k大數。

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int t,n,totp,totq,lim;
struct hh
{
    int opt,t,v,k,id; 
}p[200005],q[200005];
int c[20000005];
int lowbit(int x)
{
    return x&(-x);
}
void add(int pos,int v)
{
    for(;pos<=lim;pos+=lowbit(pos))
        c[pos]+=v;
}
int query(int pos)
{
    int ret=0;
    for(;pos;pos-=lowbit(pos))
        ret+=c[pos];
    return ret;
}
bool cmp(hh a,hh b)
{
    return a.t<b.t;
}
bool cmp2(hh a,hh b)
{
    return a.id<b.id;
}
int solve(int k)
{
    int l,r,mid,ret,n;
    l=1;r=lim;
    ret=lim;
    if(query(lim)<k) return -1;
    while(l<=r)
    {
        mid=l+r>>1;
        if(query(mid)>=k)
        {
            r=mid-1;
            ret=min(ret,mid);
        }
        else l=mid+1;
    }
    return ret;
}
int main()
{
    int T,i,j,a,b,z,prep,opt;
    scanf("%d",&t);
    for(T=1;T<=t;T++)
    {
        scanf("%d",&n);
        totp=totq=0;
        memset(p,0,sizeof(p));
        memset(q,0,sizeof(q));
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&opt,&a,&b);
            lim=max(lim,b);
            if(opt==1)
            {
                scanf("%d",&z);
                p[++totp].opt=1;
                p[totp].v=b;
                p[totp].t=a;
                
                p[++totp].opt=-1;
                p[totp].v=b;
                p[totp].t=z;
            }
            else
            {
                q[++totq].t=a;
                q[totq].k=b;
                q[totq].id=i;
            }
        }
        sort(p+1,p+1+totp,cmp);
        sort(q+1,q+1+totq,cmp);
        prep=1;
        for(i=1;i<=totq;i++)
        {
            while(p[prep].t<q[i].t&&prep<=totp)
            {
                add(p[prep].v,p[prep].opt);
                prep++;
            }
            q[i].v=solve(q[i].k);
        }
        sort(q+1,q+1+totq,cmp2);
        printf("Case %d:\n",T);
        for(i=1;i<=totq;i++)
            printf("%d\n",q[i].v);
    }
    return 0;
}
View Code

L-Largest Allowed Area

題目大意:求一個最大的子矩陣,要求子矩陣的和為0或1。

題解:單調隊列。

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

int t,n,m,ans;
int s[1005][1005],a[1005][1005];
char c;

int main()
{
    int i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(s,0,sizeof(s));
        memset(a,0,sizeof(a));
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                do{c=getchar();}while(c!=0&&c!=1);
                s[i][j]=c-0+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
            }
        for(i=1,ans=1;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                a[i][j]=a[i-1][j-1]-(a[i-1][j-1]>=1);
                while(i+a[i][j]<=n&&j+a[i][j]<=m&&s[i+a[i][j]][j+a[i][j]]-s[i-1][j+a[i][j]]-s[i+a[i][j]][j-1]+s[i-1][j-1]<=1)
                    a[i][j]++;
                ans=max(ans,a[i][j]);
            }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

【GYM102091】2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest