A.2295
求有多少素数对和等于n。
暴力。
#include <bits/stdc++.h> using namespace std; int ss(int n) { int i=2,a=sqrt(n); for(;i<=a;i++) if(n%i==0) return 0; return 1; } int main() { int n; while(scanf("%d",&n),n) { int sum=0; for(int i=2;i<=n/2;i++) { if(ss(i)&&ss(n-i)) sum++; } printf("%d\n",sum); } return 0; }
B.4607
给一个数能否被17整除。
同余。
#include<bits/stdc++.h> using namespace std; int main() { string s; while(cin>>s,s!="0") { int su=0; for(int i=0; s[i]; i++)su=(su*10+s[i]-'0')%17; cout<<(su?0:1)<<endl; } }
C.4681
给一个4*4的方格图,一次移动,输出结果。
暴力模拟。
#include<bits/stdc++.h> using namespace std; int a[5][5]; void left_swap() { for(int i=0;i<4;i++) for(int j=1;j<4;j++) { int k=j; while(k>=1&&a[i][k-1]==0) { swap(a[i][k],a[i][k-1]); k--; } } } void left() { for(int i=0;i<4;i++) for(int j=0;j<3;j++) if(a[i][j]==a[i][j+1]) { a[i][j]+=a[i][j+1]; a[i][j+1]=0; left_swap(); } } void right_swap() { for(int i=0;i<4;i++) for(int j=2;j>=0;j--) { int k=j; while(k<=2&&a[i][k+1]==0) { swap(a[i][k],a[i][k+1]); k++; } } } void right() { for(int i=0;i<4;i++) for(int j=3;j>=1;j--) if(a[i][j]==a[i][j-1]) { a[i][j]+=a[i][j-1]; a[i][j-1]=0; right_swap(); } } void top_swap() { for(int j=0;j<4;j++) for(int i=1;i<4;i++) { int k=i; while(k>=1&&a[k-1][j]==0) { swap(a[k][j],a[k-1][j]); k--; } } } void top() { for(int j=0;j<4;j++) for(int i=0;i<3;i++) if(a[i+1][j]==a[i][j]) { a[i][j]+=a[i+1][j]; a[i+1][j]=0; top_swap(); } } void buttom_swap() { for(int j=0;j<4;j++) for(int i=2;i>=0;i--) { int k=i; while(k<=2&&a[k+1][j]==0) { swap(a[k][j],a[k+1][j]); k++; } } } void buttom() { for(int j=0;j<4;j++) for(int i=3;i>=1;i--) if(a[i][j]==a[i-1][j]) { a[i][j]+=a[i-1][j]; a[i-1][j]=0; buttom_swap(); } } int main() { int n; while(cin>>n) { memset(a,0,sizeof(a)); for(int i=0;i<4;i++) for(int j=0;j<4;j++) cin>>a[i][j]; if(n==0) { left_swap(); left(); } else if(n==1) { right_swap(); right(); } else if(n==2) { top_swap(); top(); } else if(n==3) { buttom_swap(); buttom(); } for(int i=0;i<4;i++) { for(int j=0;j<4;j++) if(j==0)cout<<a[i][j]; else cout<<" "<<a[i][j]; cout<<endl; } } return 0; }
D.4682
n个部下,每个部下需要Bi分钟交待任务,让后Ji分钟后完成任务。确定一个顺序,使得最早完成任务。
贪心,按照Ji从大到小排序,然后求解。
#include<bits/stdc++.h> using namespace std; #define ll long long struct ydw{ ll b,j; }qu[1005]; bool cmp(ydw x,ydw y) { if(x.j!=y.j)return x.j>y.j; return x.b>y.b; } int main() { ll i,n,k; int kk=1; while(scanf("%I64d",&n),n!=0) { for(i=0;i<n;i++) { cin>>qu[i].b>>qu[i].j; } sort(qu,qu+n,cmp); ll s=0; for(i=0;i<n;i++) { s+=qu[i].b; for(k=0;k<i;k++) { qu[k].j-=qu[i].b; } } ll m=0; for(i=0;i<n;i++)m=max(m,qu[i].j); printf("Case %d: ",kk++); cout<<s+m<<endl; } return 0; }
E.3476
给n个时间,问是否矛盾。
暴力。
#include<stdio.h> int main(){ int i,j,n,h,m,s,h1,m1,s1; while(scanf("%d",&n)!=EOF,n){ int f=1,a[1441]={0}; for(i=0;i<n;i++){ scanf("%d:%d-%d:%d",&h,&m,&h1,&m1); s=h*60+m;s1=h1*60+m1; if(f){ for(j=s;j<s1;j++){ if(a[j]){ f=0;break; } a[j]=1; } } } if(f)printf("no conflict\n"); else printf("conflict\n"); } }
F.4499
给一串AB串,操作1选1个位子把A改成B,B改成A,操作2选1个k,改变[1,k]的值。
思维,倒着来看。
如果s[i]='B'那么需要改,如果修改长度>=2那么肯定选操作2,否则选操作1。
#include<cstdio> int n,g,i,j; char ch; bool s[1000005],k; int main() { scanf("%d\n",&n); while(i<=n) { s[++i]=(ch=getchar())=='A'?1:0; } i--; while(i>=1) { if(k^s[i])i--; else { j=-1; while(!(k^s[i]))i--,j++; if(j)k^=1; g++; } } printf("%d",g); }
G.3587
输出A,B的最大公约数。
欧几里得算法。
#include<stdio.h> __int64 gcd(__int64 a,__int64 b){ __int64 r=a%b; while(r){ a=b;b=r;r=a%b; } return b; } int main(){ int t; scanf("%d",&t); while(t--){ __int64 a,b; scanf("%I64d%I64d",&a,&b); printf("%I64d\n",gcd(a,b)); } return 0; }
H.3451
村庄之间已经有一些道路,你的工作就是修建一些道路,使所有村庄都连通起来,所有道路的长度都是最小的。
最小生成树,已经有的路权值为0。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define MAXN 100+5 #define MAXM 5000+5 int Map[MAXN][MAXN]; int F[MAXN]; int n,m,fx,fy,cnt; struct edge { int u; int v; int w; }edges[MAXM]; bool cmp(edge a,edge b) { return a.w<b.w; } int Find(int x) { return F[x]==-1?x:F[x]=Find(F[x]); } int Kruskal() { sort(edges,edges+m,cmp); int ans=0; for(int i=0;i<m;i++) { int u,v,w; u=edges[i].u; v=edges[i].v; w=edges[i].w; fx=Find(u); fy=Find(v); if(fx!=fy) { ans+=w; cnt++; F[fx]=fy; } if(cnt==n-1)break; } if(cnt<n-1)return -1; else return ans; } int main() { scanf("%d",&n); m=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int w; scanf("%d",&w); if(i==j||i>j)continue;//多余的路径 edges[m].u=i; edges[m].v=j; edges[m++].w=w; } } memset(F,-1,sizeof(F)); int Q,a,b; scanf("%d",&Q); for(int i=0;i<Q;i++) { scanf("%d%d",&a,&b); fx=Find(a); fy=Find(b); if(fx!=fy) { F[fx]=fy; cnt++; } } int ans=Kruskal(); printf("%d\n",ans); return 0; }
I.3675
给三条边,问是否等边等腰斜角。
直接判一判就行。
#include<bits/stdc++.h> using namespace std; #define ll __int64 int main() { int T,ca=1; cin>>T; while(T--) { ll a[3]; cin>>a[0]>>a[1]>>a[2]; sort(a,a+3); cout<<"Case #"<<ca++<<": "; if(a[0]+a[1]<=a[2])cout<<"invalid!\n"; else if(a[0]==a[1]&&a[1]==a[2])cout<<"equilateral\n"; else if(a[0]==a[1]||a[1]==a[2])cout<<"isosceles\n"; else cout<<"scalene\n"; } }
J.2913
[1,M]且可以整除a[i]的个数。
容斥,如果是奇数,那么个数ans+=m/lcm,如果是偶数,那么个数ans-=m/lcm,其中lcm为当前选中数的最小公倍数。
#include<bits/stdc++.h> using namespace std; int main() { int n,m,a[10]; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<n;i++)scanf("%d",&a[i]); int ans=0; for(int i=1;i<(1<<n);i++) { int lcm=1,cnt=0; for(int j=0;j<n;j++) if(i&(1<<j)) { lcm=a[j]/__gcd(a[j],lcm)*lcm; cnt++; } if(cnt&1)ans+=m/lcm; else ans-=m/lcm; } printf("%d\n",ans); } return 0; }