1、110501/10035 Primary Arithmetic (小学生算术)
注意输出格式

#include<stdio.h> #include<string.h> #include<math.h> #include<ctype.h> #include<algorithm> using namespace std; typedef long long lld; lld a,b; int main() { while(scanf("%lld",&a)!=EOF) { scanf("%lld",&b); if(a==0&&b==0) break; int cnt=0; int tot=0; while(a!=0||b!=0) { if(a%10+b%10+cnt>=10) { cnt=1; tot++; } else { cnt=0; } a/=10; b/=10; } if(tot==0)printf("No "); else printf("%d ",tot); if(tot<=1) printf("carry operation. "); else printf("carry operations. "); } return 0; }
2、110502/10018 Reverse and Add (反转相加)

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; typedef long long lld; lld rever(lld a) { lld b=0; while(a) { b=b*10+a%10; a/=10; } return b; } bool isp(lld a) { int num[100],i=0,j; while(a) { num[i++]=a%10; a/=10; } for(j=0;j<=i/2;j++) { if(num[j]!=num[i-1-j])return false; } return true; } int main() { int N; scanf("%d",&N); while(N--) { lld a; scanf("%lld",&a); int cnt=0; while(!isp(a)) { a=a+rever(a); cnt++; } printf("%d %lld ",cnt,a); } return 0; }
3、110504/10127 Ones (仅由 1 组成的数)

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<ctype.h> using namespace std; int calc(int n,int len,int tmp) { int cnt=len; while(tmp!=0) { if(tmp>=n) { tmp=tmp%n; } else { cnt++; tmp=tmp*10+1; } } return cnt; } int main() { int n; while(scanf("%d",&n)!=EOF) { int i,len=0,x=n,t=0; while(x) { len++; x/=10; t=t*10+1; } int tot=calc(n,len,t); printf("%d ",tot); } return 0; }
4、110503/701 The Archeologist’s Dilemma (考古学家的烦恼)
任何一个数都可以表示为N*10^K (科学计数法),N*10^K<=2^E<(N+1)*10^K,即,log2(N)+K*log2(10)<=E<log2(N+1)+K*log2(10),即
log2(N)<=E<log2(N+1),又因为设两边为a,b ,b-a=log2((N+1)/N)<log2(2)=1,所以区间属于(0,1)必然覆盖一个解

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<stdlib.h> using namespace std; const int INF=1000000000; int main() { int n; while(scanf("%d",&n)!=EOF) { double a=log(n*1.0)/log(2.0); double b=log((n+1)*1.0)/log(2.0); double c=log(10.0)/log(2.0); int i,len=0; while(n) { len++; n/=10; } for(i=len+1;;i++) { int x=ceil(a+i*c); int y=floor(b+i*c); if(x<=y) { printf("%d ",x); break; } if(i>=INF) { printf("no power of 2 "); break; } } } return 0; }
5、110505/847 A Multiplication Game (乘法游戏)
此题是博弈问题,先手尽量小后手尽量大

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; const double ex=1.0e-8; int dblcmp(double x) { if(fabs(x)<ex)return 0; return x-ex>0?1:-1; } int main() { double n; while(scanf("%lf",&n)!=EOF) { while(dblcmp(n-18)>0) { n/=18; } if(dblcmp(n-9)>0)printf("Ollie wins. "); else printf("Stan wins. "); } return 0; }
6、 110506/10105 Polynomial Coefficients (多项式系数)

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; int co[20]; typedef long long lld; lld calc(int m,int n) { lld ta=1,tb=1,tc=1; int i; for(i=m;i>n;i--)ta=ta*i; for(i=1;i<=m-n;i++)tc=tc*i; return ta/(tc); } int main() { int n,k; while(scanf("%d%d",&n,&k)!=EOF) { int i; lld tot=1; int sum=0; for(i=0;i<k;i++) { scanf("%d",&co[i]); tot*=calc(n-sum,co[i]); sum+=co[i]; } printf("%lld ",tot); } } /* 5 5 1 0 2 0 2 */
7、110507/10077 The Stern-Brocot Number System (Stern-Brocot 代数系统)
著名的farey数列,可以求出所有的有理分数,中序遍历按从小到大的顺序排列,所以可以二分查找

#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; typedef long long lld; struct NODE { int m,n; }; NODE a,b; int cmp(NODE c,NODE d) { lld ra=c.m*d.n,rb=c.n*d.m; if(ra>rb)return 1; else if(ra==rb)return 0; else return -1; } void search(int m,int n) { if(m==1&&n==1) { printf("I "); return; } int d=1; bool sta=true; NODE t,R,Pre,Gp; t.m=m;t.n=n; R.m=1;R.n=1; int W; int res=cmp(t,R); if(res==1) { Pre.m=b.m;Pre.n=b.n; W=1; } else if(res==-1) { Pre.m=a.m;Pre.n=a.n; W=0; } while(1) { res=cmp(t,R); if(res==0) { printf(" "); return; } else if(res==1) { printf("R"); if(W==0) { Pre.m=Gp.m; Pre.n=Gp.n; W=1; } } else { printf("L"); if(W==1) { Pre.m=Gp.m; Pre.n=Gp.n; W=0; } } Gp.m=R.m; Gp.n=R.n; R.m=R.m+Pre.m; R.n=R.n+Pre.n; } } int main() { int i; a.m=0;a.n=1; b.m=1,b.n=0; int m,n; while(scanf("%d%d",&m,&n)!=EOF) { if(m==1&&n==1)break; search(m,n); } return 0; }
8、110508/10202 Pairsumonious Numbers (两两之和)
首先将两两和从小到大排序,则最小的必然是a1+a2,a1+a3,之后可能是a2+a3或者a1+a4,则可以求出a1,a2,a3,之后依次求出a4~aN,每次求出ai,将a1~ai的所有组合数都标记一下,则下面遍历到的第一个数必然是a[i+1]+a[1],因为a[i+1]+a[x](x>1)或者a[x]+a[1](x>i+1)必然排在a[i+1]+a[1]的后面

#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<ctype.h> using namespace std; typedef long long lld; int sum[100]; int a[15]; int vis[100]; int main() { int N,M; while(scanf("%d",&N)!=EOF) { int i,j,k,t; M=N*(N-1)/2; for(i=0;i<M;i++) { scanf("%d",&sum[i]); } sort(sum,sum+M); for(i=2;i<M;i++) { a[1]=(sum[0]+sum[1]-sum[i])/2; a[2]=sum[0]-a[1]; a[3]=sum[1]-a[1]; if(a[2]+a[3]!=sum[i])continue; memset(vis,0,sizeof(vis)); vis[i]=1; int s=2; bool flag=true; for(j=4;j<=N&&flag;j++) { while(vis[s])s++; a[j]=sum[s]-a[1]; vis[s]=1; for(k=2;k<j&&flag;k++) { for(t=s+1;t<M&&flag;t++) { if(!vis[t]&&a[j]+a[k]==sum[t]) { vis[t]=1; break; } } if(t>=M)flag=false; } } if(flag)break; } if(i>=M)printf("Impossible "); else { for(i=1;i<=N;i++) { if(i>1)printf(" "); printf("%d",a[i]); } printf(" "); } } return 0; }