CHD 2015迎新杯题解
简析:计算 n 的二进制表示里面 1 的个数
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int bitcount(int x) { 7 int ans = 0; 8 while(x) { 9 if(x & 1) ans++; 10 x >>= 1; 11 } 12 return ans; 13 } 14 15 int main() 16 { 17 // freopen("in.txt", "r", stdin); 18 // freopen("out.txt", "w", stdout); 19 20 int T; scanf("%d", &T); 21 while(T--) { 22 int n; scanf("%d", &n); 23 printf("%d\n", bitcount(n)); 24 } 25 26 return 0; 27 }
简析:这个题主要分成四种情况讨论:
一荤一素,两荤两素,一素两荤,一荤两素。
因为不管是饭和汤,还是面条,都会对应上面四种情况,所以我把饭和汤,面条写的一个函数里。
详细见代码,请各位大神指教。----wzm
1 #include <iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 int a[15],b[15],c[15],d[15],e[15]; 7 int a1,b1,c1,d1,e1; 8 int sum[5],ans,minn,maxn; 9 void f(int s){//一饭一汤,面条 10 for(int x = 1; x<=a1; x++){ 11 for(int y = 1; y<=b1; y++){ 12 if((s+a[x]+b[y])>=minn&&(s+a[x]+b[y])<=maxn){ 13 ans++; 14 } 15 } 16 } 17 for(int z = 1; z<=c1; z++){ 18 if((s+c[z])>=minn&&(s+c[z])<=maxn){ 19 ans++; 20 } 21 } 22 } 23 void solve(){ 24 int t; 25 scanf("%d",&t); 26 while(t--){ 27 cin>>a1>>b1>>c1>>d1>>e1; 28 for(int i = 1; i<=a1; i++) cin>>a[i]; 29 for(int i = 1; i<=b1; i++) cin>>b[i]; 30 for(int i = 1; i<=c1; i++) cin>>c[i]; 31 for(int i = 1; i<=d1; i++) cin>>d[i]; 32 for(int i = 1; i<=e1; i++) cin>>e[i]; 33 cin>>minn>>maxn; 34 ans = 0; 35 for(int i = 1; i<=d1; i++){//一荤一素 36 for(int j = 1; j<=e1; j++){ 37 { 38 int s = d[i]+e[j]; 39 f(s); 40 } 41 } 42 } 43 for(int i = 1; i<=d1; i++)//两荤两素 44 for(int j = i+1; j<=d1; j++){ 45 for(int p = 1; p<=e1; p++){ 46 for(int q = p+1; q<=e1; q++){ 47 int s = d[i]+d[j]+e[p]+e[q]; 48 f(s); 49 } 50 } 51 } 52 for(int i = 1; i<=d1; i++){//一荤两素 53 for(int p = 1; p<=e1; p++) 54 for(int q = p+1; q<=e1; q++){ 55 int s = d[i]+e[p]+e[q]; 56 f(s); 57 } 58 } 59 for(int p = 1; p<=e1; p++){//两荤一素 60 for(int i = 1;i<=d1; i++){ 61 for(int j = i+1; j<=d1; j++){ 62 int s = d[i]+d[j]+e[p]; 63 f(s); 64 } 65 } 66 } 67 printf("%d\n",ans); 68 } 69 } 70 int main() 71 { 72 solve(); 73 return 0; 74 }
简析:可以先将角度转换为最小的单位的值,再按照题意模拟
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 8 struct Node{ 9 int d,m,s; 10 int x; 11 }a[55]; 12 13 struct node{ 14 double l; 15 int id; 16 }b[55]; 17 18 int cmp(node n1,node n2){ 19 return n1.l < n2.l; 20 } 21 22 int sum,vis[55],n; 23 double len[55]; 24 25 void solve(){ 26 int sum0 = (n-2)*180*3600; 27 int f = sum - sum0; 28 if( (long long) f*f > 1600*n){ 29 puts("Poor Prince Cao Tan"); 30 return; 31 } 32 f = -f; 33 int v = f/n; 34 int r = f%n; 35 // printf("v = %d r = %d\n",v,r); 36 memset(vis,0,sizeof(vis)); 37 sort(b+1,b+n+1,cmp); 38 for(int i = 1;i <= n;i++){ 39 int bl,br,jl,jr; 40 if(b[i].id == n){ 41 bl = 1; 42 br = n-1; 43 jl = 1; 44 jr = n; 45 } 46 else if(b[i].id == 1){ 47 bl = n; 48 br = 2; 49 jl = 1; 50 jr = 2; 51 } 52 else{ 53 bl = b[i].id -1; 54 br = b[i].id +1; 55 jl = b[i].id; 56 jr = b[i].id+1; 57 } 58 if(len[bl] > len[br]){ 59 swap(bl,br); 60 swap(jl,jr); 61 } 62 // printf("bl = %d br = %d jl = %d jr = %d\n",bl,br,jl,jr); 63 if(!vis[jl]){ 64 a[jl].x += v; 65 if(abs(r)){ 66 a[jl].x += r/abs(r); 67 int fuhao = r/abs(r); 68 if(fuhao == -1) r++; 69 else r--; 70 } 71 vis[jl] = 1; 72 } 73 if(!vis[jr]){ 74 a[jr].x += v; 75 if(abs(r)){ 76 a[jr].x += r/abs(r); 77 int fuhao = r/abs(r); 78 if(fuhao == -1) r++; 79 else r--; 80 } 81 vis[jr] = 1; 82 } 83 } 84 for(int i = 1;i <= n;i++){ 85 int c1 = a[i].x/3600; 86 int c2 = (a[i].x-c1*3600)/60; 87 int c3 = a[i].x-c1*3600-c2*60; 88 a[i].d = c1;a[i].m = c2;a[i].s = c3; 89 } 90 for(int i = 1;i <= n;i++) printf("%d %d %d\n",a[i].d,a[i].m,a[i].s); 91 } 92 93 int main(){ 94 int T; 95 scanf("%d",&T); 96 while(T--){ 97 scanf("%d",&n); 98 sum = 0; 99 for(int i = 1;i <= n;i++){ 100 scanf("%d %d %d",&a[i].d,&a[i].m,&a[i].s); 101 a[i].x = a[i].d*3600 + a[i].m*60+a[i].s; 102 sum += a[i].x; 103 } 104 for(int i = 1;i <= n;i++){ 105 scanf("%lf",&b[i].l); 106 b[i].id = i; 107 len[i] = b[i].l; 108 } 109 solve(); 110 } 111 return 0; 112 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 const int maxn=20; 8 double L[maxn]; 9 10 struct angle 11 { 12 int d,m,s; 13 }Zero,One,b[maxn],v[maxn],a[maxn]; 14 15 angle Plus(angle A,angle B) 16 { 17 angle tmp=Zero; 18 tmp.s=A.s+B.s; 19 if(tmp.s>=60) tmp.s-=60,tmp.m++; 20 tmp.m+=A.m+B.m; 21 if(tmp.m>=60) tmp.m-=60,tmp.d++; 22 tmp.d+=A.d+B.d; 23 return tmp; 24 } 25 26 angle Minus(angle A,angle B) 27 { 28 angle tmp; 29 tmp.s=A.s-B.s; 30 tmp.m=A.m-B.m; 31 tmp.d=A.d-B.d; 32 while(tmp.s<0) tmp.s+=60,tmp.m--; 33 while(tmp.m<0) tmp.m+=60,tmp.d--; 34 return tmp; 35 } 36 37 angle Divide(angle A,int B) 38 { 39 angle tmp; 40 tmp.d=A.d/B; 41 tmp.m=A.m+A.d%B*60; 42 tmp.s=A.s+tmp.m%B*60; 43 tmp.m/=B; 44 tmp.s/=B; 45 return tmp; 46 } 47 48 angle Mod(angle A,int B) 49 { 50 angle tmp; 51 tmp.s=(A.d*3600+A.m*60+A.s)%B; 52 return tmp; 53 } 54 55 bool Smaller(angle A,angle B) 56 { 57 if(A.d!=B.d) return A.d<B.d; 58 if(A.m!=B.m) return A.m<B.m; 59 return A.s<B.s; 60 } 61 62 struct point 63 { 64 int id; 65 double x,y; 66 }p[maxn]; 67 68 bool cmp(point A,point B) 69 { 70 if(A.x!=B.x) return A.x<B.x; 71 return A.y<B.y; 72 } 73 74 int main(void) 75 { 76 int T; 77 scanf("%d",&T); 78 Zero.d=Zero.m=Zero.s=0; 79 One.d=One.m=0;One.s=1; 80 while(T--) 81 { 82 int n,flag=0; 83 scanf("%d",&n); 84 angle sum=Zero,tot=Zero,delta,q,r; 85 for(int i=1;i<=n;i++) 86 { 87 scanf("%d%d%d",&b[i].d,&b[i].m,&b[i].s); 88 sum=Plus(sum,b[i]); 89 } 90 for(int i=1;i<=n;i++) scanf("%lf",L+i); 91 tot.d=(n-2)*180; 92 if(Smaller(sum,tot)) {flag=1; delta=Minus(tot,sum);} 93 else delta=Minus(sum,tot); 94 if(delta.d*3600+delta.m*60+delta.s>40*sqrt(n)) {puts("Poor Prince Cao Tan");continue;} 95 q=Divide(delta,n); 96 r=Mod(delta,n); 97 for(int i=1;i<=n;i++) 98 { 99 double x=L[i],y=L[i-1<1?n:i-1]; 100 if(x>y) swap(x,y); 101 p[i].id=i; 102 p[i].x=x; 103 p[i].y=y; 104 } 105 sort(p+1,p+1+n,cmp); 106 memset(v,0,sizeof(v)); 107 for(int i=1;i<=n;i++) 108 { 109 if(!Smaller(Zero,r)&&!Smaller(r,Zero)) break; 110 int pos=p[i].id; 111 v[pos]=Plus(v[pos],One); 112 r=Minus(r,One); 113 } 114 for(int i=1;i<=n;i++) 115 { 116 if(flag) a[i]=Plus(Plus(b[i],v[i]),q); 117 else a[i]=Minus(Minus(b[i],v[i]),q); 118 printf("%d %d %d\n",a[i].d,a[i].m,a[i].s); 119 } 120 } 121 return 0; 122 }
简析:dp[i] 表示花费 i 时间做事情能够得到的最大效率,最后再 O(n) 扫一遍 (t-i) * (dp[i] + 1) 得到最大值
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int MAXT=1e3+10; 6 int dp[MAXT]; 7 int main(){ 8 int T; 9 scanf("%d",&T); 10 while(T--){ 11 int n,t; 12 scanf("%d%d",&t,&n); 13 memset(dp,0,sizeof(dp)); 14 for(int i=1;i<=n;i++) { 15 int a,b; 16 scanf("%d%d",&a,&b); 17 for(int j=t;j>=a;j--)dp[j]=max(dp[j],dp[j-a]+b); 18 } 19 int ans=0; 20 for(int i=0;i<t;i++) ans=max(ans,(t-i)*( dp[i]+1) ); 21 printf("%d\n",ans); 22 } 23 return 0; 24 }
简析:用并查集处理每一对能够发生化学反应的药剂,反应次数,
假设一个连通块的大小为 x ,则发生化学反应的次数为 x-1 (x >= 2)将所有的连通块的反应次数加起来即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <bitset> 7 #include <cmath> 8 using namespace std; 9 10 int s[1000010]; 11 12 int Find(int x) 13 { 14 if(s[x] == 0) return x; 15 return s[x] = Find(s[x]); 16 } 17 18 void SetUnion(int r1, int r2) 19 { 20 s[r2] = r1; 21 } 22 23 int main() 24 { 25 int t, n, k; 26 int x, y; 27 int r1, r2; 28 int ans; 29 scanf("%d", &t); 30 while(t--) 31 { 32 ans = 0; 33 memset(s, 0, sizeof(s)); 34 scanf("%d%d", &n, &k); 35 for(int i = 1 ; i <= k ; i++) 36 { 37 scanf("%d%d", &x, &y); 38 r1 = Find(x); 39 r2 = Find(y); 40 if(r1 != r2) 41 { 42 SetUnion(r1, r2); 43 } 44 } 45 for(int i = 1 ; i <= n ; i++) 46 if(s[i] == 0) ans++; 47 ans = n - ans; 48 printf("%d\n",ans); 49 } 50 return 0; 51 }
简析:巴什博奕 戳这
1 #include <cstdio> 2 3 int main() 4 { 5 //freopen("in.txt", "r", stdin); 6 //freopen("out.txt", "w", stdout); 7 8 int T; scanf("%d", &T); 9 while(T--) { 10 int n, m; 11 scanf("%d%d", &n, &m); 12 if(n % (m + 1) == 0) printf("Bob\n"); 13 else printf("Alex\n"); 14 } 15 return 0; 16 }
简析:倒着扫一遍,维护一个最大值max,如果当前的 a[i] > max ,更新 max 的值,
否则将 a[i] 卖掉,得到 max-a[i] 的钱
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long LL; 5 const int maxn = 1e6 + 10; 6 LL a[maxn]; 7 8 int main(void) 9 { 10 int T; 11 scanf("%d",&T); 12 while(T--) 13 { 14 int N; 15 scanf("%d",&N); 16 for(int i = 1; i <= N; i++) scanf("%I64d",a+i); 17 LL ans = 0LL, Max = 0LL; 18 for(int i = N; i >= 1; i--) 19 { 20 if(a[i] > Max) Max = a[i]; 21 else ans += Max - a[i] ; 22 } 23 printf("%I64d\n",ans); 24 } 25 return 0; 26 }
简析:二分每个人分到的蛋糕大小 x ,每次check 能够分出的块数 tot 是否 >= n
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <ctime> 5 using namespace std; 6 7 const int maxn = 20000 + 10; 8 const int INF = 0x3f3f3f3f; 9 10 int n, m; 11 int a[maxn]; 12 13 bool check(int x) { 14 long long tot = 0; 15 for(int i = 0; i < m; i++) { 16 tot += a[i] / x; 17 } 18 return tot >= n; 19 } 20 21 int main() 22 { 23 // freopen("in.txt", "r", stdin); 24 // freopen("out.txt", "w", stdout); 25 26 int T; scanf("%d", &T); 27 while(T--) { 28 scanf("%d%d", &n, &m); 29 for(int i = 0; i < m; i++) scanf("%d", a + i); 30 31 if(!check(1)) { 32 printf("0\n"); 33 continue; 34 } 35 36 int L = 1, R = INF; 37 while(L < R) { 38 int mid = (L + R) / 2 + 1; 39 if(check(mid)) L = mid; 40 else R = mid - 1; 41 } 42 43 printf("%d\n", L); 44 } 45 46 // printf("Time used = %.3f\n", (double)clock() / CLOCKS_PER_SEC); 47 return 0; 48 }
I.拉面女神的魔盒
简析: 按照题意bfs,状态数不会超过1e6 ,所以可以bfs一遍预处理出所有的答案
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 1000000; 8 typedef pair<int, int> pii; 9 int tmp[7], cur[7], ans[maxn]; 10 11 int id(int * a) 12 { 13 int ret = a[1]; 14 for(int i = 2; i <= 6; i++) 15 ret = ret * 10 + a[i]; 16 return ret; 17 } 18 19 void change(int no) 20 { 21 for(int i = 6; i >= 1; i--) 22 cur[i] = no % 10, no /= 10; 23 return; 24 } 25 26 void BFS() 27 { 28 queue<pii> q; 29 q.push(pii(0,0)); 30 ans[0] = 0; 31 while(!q.empty()) 32 { 33 pii tmp = q.front(); q.pop(); 34 int now = tmp.first, t = tmp.second; 35 change(now); 36 int Next, n[7], sum = 0, odd = 0; 37 memcpy(n, cur, sizeof(n)); 38 for(int i = 1; i <= 6; i++) 39 { 40 sum += cur[i]; 41 if(cur[i] % 2) odd++; 42 } 43 44 n[1] = (cur[1] + 1) % 10; 45 Next = id(n); 46 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 47 48 n[1] = (cur[1] + 9) % 10; 49 Next = id(n); 50 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 51 52 n[1] = cur[1]; 53 54 if(odd == 3) 55 { 56 n[2] = (cur[2] + 1) % 10; 57 Next = id(n); 58 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 59 60 n[2] = (cur[2] + 9) % 10; 61 Next = id(n); 62 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 63 64 n[2] = cur[2]; 65 } 66 67 n[3] = (cur[3] + 7) % 10; 68 Next = id(n); 69 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 70 n[3] = cur[3]; 71 72 n[4] = (cur[4] + (sum % 9 + 1) ) % 10; 73 Next = id(n); 74 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 75 n[4] = cur[4]; 76 77 if(cur[1] + cur[3] + cur[5] == 9) 78 { 79 n[5] = (cur[5] + 1) % 10; 80 Next = id(n); 81 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 82 83 n[5] = (cur[5] + 9) % 10; 84 Next = id(n); 85 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 86 87 n[5] = cur[5]; 88 } 89 90 if(cur[2] == 0) 91 { 92 n[6] = (cur[6] + 7) % 10; 93 Next = id(n); 94 if(ans[Next] == -1){q.push(pii(Next, t+1)); ans[Next] = t + 1;} 95 } 96 97 } 98 return; 99 } 100 101 int main(void) 102 { 103 // freopen("in.txt","r",stdin); 104 //freopen("out.txt","w",stdout); 105 memset(ans, -1, sizeof(ans)); 106 BFS(); 107 int T; 108 scanf("%d", &T); 109 while(T--) 110 { 111 for(int i = 1; i <= 6; i++) scanf("%d", tmp + i); 112 printf("%d\n", ans[id(tmp)]); 113 } 114 return 0; 115 }
简析:
~end~