A.3232
n个物品,换取要花积分,问刚好花完积分能换最大多少价值的物品。
多重背包。
#include <bits/stdc++.h> using namespace std; int t[1005]; int main() { int m,n,i,a,b,c,T,j,k; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); memset(t,0,sizeof(t)); for(k=0;k<n;k++) { scanf("%d%d%d",&a,&b,&c); if(t[c]<a) t[c]=a; for(i=0;i<=b;i++) { for(j=m;j>=c;j--) { if(j-c*i>=0&&t[j-c*i]&&t[j-c*i]+a*i>t[j]) t[j]=t[j-c*i]+a*i; } } } if(t[m]) printf("The maximum value is %d. ",t[m]); else printf("This is impossible. "); } return 0; }
B.3196
医生优先处理级别最高的病人,给n件发生的事,对于每个OUT输出。
优先队列。
#include <bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f struct node { int a, b; friend bool operator<(node a, node b) { if(a.a != b.a) return a.a < b.a; return a.b > b.b; } }; int main() { int n; while(cin >> n) { priority_queue<node> qu[4]; string str; int cnt = 0; for(int i = 1; i<= n; i++) { cin >>str; if(str == "IN") { int a,b; cin >> a >> b; qu[a].push({b,++cnt}); } else if(str == "OUT") { int a; cin >> a; if(!qu[a].empty()) cout <<qu[a].top().b << endl, qu[a].pop(); else cout << "EMPTY "; } } } return 0; }
C.4705
给一个数字串问取出一个连续的若干位能组成的最大素数。
暴力。
#include <bits/stdc++.h> using namespace std; int main() { string str; while(cin >>str) { int maxx = -1; for(int i = 0; i < str.size(); i++) { int temp = 0; for(int j = i; j < str.size(); j++) { temp = temp*10 + str[j]-'0'; int f = 0; for(int k = 2; k <= sqrt(temp); k++) { if(temp % k == 0) {f = 1; break;} } if(temp != 1 && !f) maxx = max(maxx,temp); } } if(maxx == -1) cout << "None "; else cout << maxx <<endl; } return 0; }
D.3293
给一个数A,一个数B,问AB的二进制中有几个数不同。
taozi的暴力。
#include<stdio.h> int main() { __int64 a,b; while(scanf("%I64d%I64d",&a,&b)!=EOF,a||b) { int c[65]={0},d[65]={0}; int c1=64,d1=64; while(a) { c[c1--]=a%2; a/=2; } while(b) { d[d1--]=b%2; b/=2; } int ans=0; for(int i=0;i<=64;i++) if(c[i]!=d[i]) ans++; printf("%d ",ans); } return 0; }
zenghuan_的位运算。
1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位;
2. A | B, 得到的结果D中的1的位表明了A和B在该位至少有一个为1的位,包含了A 与 B 都是1的位数,
经过前两步的位运算,,C 中1的位表明了A 和 B在该位都是1,D中为0的位表明了A 和 B 在该位都是0 ,所以进行第三步。
3. C ^ D,E 中为1的位表明了A 和 B不同的位。
#include<bits/stdc++.h> using namespace std; int main() { long long a,b,c,d,e; while(cin>>a>>b) { if(a==0&&b==0)break; c=a&b; d=a|b; e=a^b; long long sum=0; while(e!=0) { e=((e-1)&e); sum++; } cout<<sum<<endl; } return 0; }
E.2938
m*n的矩阵,绕圈填。
模拟。
#include <bits/stdc++.h> using namespace std; int number; int n,m,jishu; char arr[55][55]; int main() { cin>>n>>m; char s='A'; int t=n/2+n%2; for(int i=0;i<t;i++){ for(int j=i;j<=m-i-1&&jishu<n*m;j++){ arr[i][j]=s++; jishu++; if(s=='Z'+1) s='A'; } for(int j=i+1;j<=n-i-1&&jishu<n*m;j++){ arr[j][m-i-1]=s++; jishu++; if(s=='Z'+1) s='A'; } for(int j=m-i-2;j>=i&&jishu<n*m;j--){ arr[n-i-1][j]=s++; jishu++; if(s=='Z'+1) s='A'; } for(int j=n-i-2;j>=i+1&&jishu<n*m;j--){ arr[j][i]=s++; jishu++; if(s=='Z'+1) s='A'; } } for(int i=0;i<n;i++) for(int j=0;j<m;j++){ cout << " " << arr[i][j]; if(j==m-1) cout << endl; } return 0; }
F.2763
求(0! + 1! + 2! + 3! + 4! + ... + n!)%m。
思维,首先n>m的部分都是0,1!%m和2!%m那么根据乘法的同余2!=1%m*2%m。
#include<stdio.h> #define ll __int64 int main() { int t; char n[105]; scanf("%d",&t); while(t--) { ll N=0,M; scanf("%s%I64d",n,&M); for(int i=0;n[i];i++) { if(N>=M){N=M;break;} N=N*10+n[i]-'0'; } ll ans=1,sum=1; for(int i=1;i<=N;i++) sum=(sum+ans*i%M)%M,ans=ans*i%M; printf("%I64d ",sum%M); } return 0; }
G.4764
一个n×n的正方形,现在你在正方形的左下角,每次你可以顺时针走n+1单元的距离,求多少次之后你可以回到起点。
找规律。
#include<stdio.h> int main(){ __int64 n,s; while(scanf("%I64d",&n)!=EOF){ if(n%2){ if((n+1)%4) s=2*n+1; else s=n+1; } else s=4*n+1; printf("%I64d ",s); } return 0; }
H.4781
ax3+bx2+cx+d=0 ,给出(a,b,c,d)求x。
暴力,由于根的范围很小,并且保留两位小数。注意在比较double会有误差,要取fabs<=1e-5。
#include<stdio.h> #include<math.h> int main(){ float a,b,c,d; scanf("%f%f%f%f",&a,&b,&c,&d); int i,f=1; for(i=-10000;i<=10000;i++){ float x=i*1.0/100; if(fabs(a*x*x*x+b*x*x+c*x+d)<=1e-5){ if(f){ printf("%.2f",x);f=0; } else printf(" %.2f",x); } } printf(" "); }
I.2955
n个点m条无向边,问至少加多少条边使得全图连通。
并查集模板题。
#include<bits/stdc++.h> using namespace std; int F[101],T; int Find(int x) { return F[x]==x? x:Find(F[x]); } int main(){ int N,M,A,B; while(cin>>N>>M) { for(int i=1;i<=N;i++) F[i]=i; T=N-1; for(int i=0;i<M;i++) { cin>>A>>B; int x=Find(A); int y=Find(B); if(x!=y) { F[x]=y; T--; } } cout<<T<<endl; } }
J.3207
n个点m条无向边,问C到D的最短路。
floyd最短路模板题,这里用dijstra也行。
#include<bits/stdc++.h> using namespace std; int n,m,ss[1005][1005]; void dij(int a,int b) { int dis[n+1][n+1]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=ss[i][j]; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(dis[i][j]>dis[k][j]+dis[i][k]) dis[i][j]=dis[k][j]+dis[i][k]; if(dis[a][b]==0x3f3f3f3f)cout<<"NO"<<endl; else cout<<dis[a][b]<<endl; } int main() { int a,b,c; cin>>n>>m; memset(ss,0x3f,sizeof(ss)); for(int i=0;i<m;i++) { cin>>a>>b>>c; ss[a][b]=ss[b][a]=c; } while(cin>>a>>b) { if(a==0&&b==0)break; dij(a,b); } return 0; }