Codeforces Beta Round #67 (Div. 2) ABCD

     A题:输入a,b(10^9),得到它们的和c,问去掉所有数的0,是否a+b=c?用__int64保险些

#include<iostream> using namespace std; void T(__int64 a,__int64 &b) { int c=1; b=0; while(a) { if(a%10) { b+=(a%10)*c; c*=10; } a/=10; } } int main() { __int64 a,b,c,d,e,f; while(scanf("%I64d%I64d",&a,&b)!=EOF) { c=a+b; T(a,d); T(b,e); T(c,f); if(d+e==f) printf("YES/n"); else printf("NO/n"); } return 0; }

      B题:在Facebook中,两个人联系有三种方式,每种方式都会在两者的关系加上一个数,求与给定一个人的关系从大到小排序,相同的按字典序。。。

#include<iostream> #include<algorithm> using namespace std; struct Name { char s[25]; int p; }N[110]; bool cmp(Name &a,Name &b) { if(a.p!=b.p) return a.p>b.p; else return strcmp(a.s,b.s)<0; } int main() { char s[25],s1[25],s2[25],s3[25]; int n,i,j,k,num; while(scanf("%s",s)!=EOF) { scanf("%d",&n); for(num=0,i=0;i<n;i++) { // getchar(); scanf("%s",s1); scanf("%s",s2); if(s2[0]=='p') { k=15; scanf("%s",s2); scanf("%s",s2); strcpy(s3,s2); s3[strlen(s2)-2]=0; scanf("%s",s2); } else if(s2[0]=='c') { k=10; scanf("%s",s2); scanf("%s",s2); strcpy(s3,s2); s3[strlen(s2)-2]=0; scanf("%s",s2); } else { k=5; scanf("%s",s2); strcpy(s3,s2); s3[strlen(s2)-2]=0; scanf("%s",s2); } if(!strcmp(s1,s)) { for(j=0;j<num;j++) if(!strcmp(s3,N[j].s)) { N[j].p+=k; break; } if(j>=num) { strcpy(N[j].s,s3); N[j].p=k; num++; } } else if(!strcmp(s3,s)) { for(j=0;j<num;j++) if(!strcmp(s1,N[j].s)) { N[j].p+=k; break; } if(j>=num) { strcpy(N[j].s,s1); N[j].p=k; num++; } } else { for(j=0;j<num;j++) if(!strcmp(s1,N[j].s)) break; if(j>=num) { strcpy(N[j].s,s1); N[j].p=0; num++; } for(j=0;j<num;j++) if(!strcmp(s3,N[j].s)) break; if(j>=num) { strcpy(N[j].s,s3); N[j].p=0; num++; } } } sort(N,N+num,cmp); for(i=0;i<num;i++) printf("%s/n",N[i].s); } return 0; }

      C题:求两个数(10^9)在一定范围内的最大公约数!先求两个数的最大公约数,然后保存它所有的因子,这里我们刚开始没反应过来能直接保存,只要扫描至它的开方就可以的。然后后面对于每一次给定的范围扫描一下,不会超时。我写了个二分还调了好久。。。

#include<iostream> #include<algorithm> using namespace std; __int64 num,m[11000000]; __int64 Gcd(__int64 a,__int64 b) { if(a<b) return Gcd(b,a); if(b==0) return a; return Gcd(b,a%b); } __int64 Bi(__int64 l) { __int64 i=0,j=num-1,k,ii=-1; while(i<=j) { k=(i+j)/2; if(m[k]>=l) { ii=k; j=k-1; } else i=k+1; } return ii; } int main() { __int64 a,b,c,n,l,r,i,ii,jj; while(scanf("%I64d%I64d",&a,&b)!=EOF) { c=Gcd(a,b); for(num=0,i=1;i*i<=c;i++) if(c%i==0) { m[num++]=i; m[num++]=c/i; } // printf("%I64d/n",num); sort(m,m+num); scanf("%I64d",&n); for(i=0;i<n;i++) { scanf("%I64d%I64d",&l,&r); ii=Bi(l); jj=Bi(r); if(jj!=-1&&m[jj]>r) jj--; if(ii<=jj&&jj!=-1) printf("%I64d/n",m[jj]); else if(jj==-1&&ii!=-1) printf("%I64d/n",m[num-1]); else printf("-1/n"); } } return 0; }

       D题:给出n个小数组,然后由m个小数组(每个都是前面n个中的一个)拼成一个大数组,求这个大数组的最大字串和。

       只要把每个小数组的和,最左边一段,最右边一段,或单独取这个小数组的最大值求出来,然后对于m个小数组,枚举初始值和结束的位置就可以。注意可能全部是负数。。。

#include<iostream> using namespace std; __int64 sum[5500],in[5500],out[5500],mm[5500],l[5500],mmax[5500]; __int64 Max(__int64 a,__int64 b) { return a<b? b:a; } int main() { __int64 n,m,i,j,num,k; __int64 s,s1,s2,s3,ii,s4; while(scanf("%I64d%I64d",&n,&m)!=EOF) { for(i=0;i<n;i++) { scanf("%I64d",&num); sum[i]=in[i]=out[i]=mm[i]=0; mmax[i]=-1000000; for(k=0,j=0;j<num;j++) { scanf("%I64d",&l[j]); if(l[j]>mmax[i]) mmax[i]=l[j]; k+=l[j]; if(k<0) k=0; else if(k>mm[i]) mm[i]=k; sum[i]+=l[j]; if(sum[i]>in[i]) in[i]=sum[i]; } for(s=0,j=num-1;j>=0;j--) { s+=l[j]; if(s>out[i]) out[i]=s; } } for(s1=0,s2=0,s3=0,s4=-1000000,s=0,i=0;i<m;i++) { scanf("%I64d",&j); j--; if(s4<mmax[j]) s4=mmax[j]; if(mm[j]>s) s=mm[j]; ii=Max(s1,s2); s1=out[j]; if(s1>s) s=s1; s2=ii+sum[j]; if(s2>s) s=s2; s3=ii+in[j]; if(s3>s) s=s3; } if(!s) s=s4; printf("%I64d/n",s); } return 0; }

你可能感兴趣的:(c,BI,ini,Facebook,IM,BT)