Codeforces Round #218 (Div. 2) 解题报告

Problem A K-Periodic Array

题意:一个数列中有1与2的序列组成,问最少修改多少个数,能使数列成为从开头开始每k个一组每组的相应位置都一样。

思路:做法就是枚举每一位上的数字1多还是2多,哪个多就让全部的数变成那一个。最后累加求和即可。

代码如下:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <utility>
 9 #include <vector>
10 #include <queue>
11 #include <stack>
12 #define INF 0x7fffffff
13 #define ll long long
14 #define eps 1e-6
15 
16 using namespace std;
17 
18 int _1[110], _2[110];
19 
20 int main()
21 {
22 //    freopen("in.txt", "Cr", stdin);
23 
24     int n, k, num[110];
25     while(scanf("%d%d", &n, &k)!=EOF){
26         for(int i=0; i<n; i++){
27             scanf("%d", &num[i]);
28         }
29         memset(_1, 0, sizeof _1);
30         memset(_2, 0, sizeof _2);
31         int ans = 0;
32         for(int j=0; j<n; j++){
33             if(num[j]==1)_1[j%k]++;
34             if(num[j]==2)_2[j%k]++;
35         }
36         for(int i=0; i<k; i++){
37             ans+=min(n/k-_1[i], n/k-_2[i]);
38         }
39         printf("%d
", ans);
40     }
41     return 0;
42 }
View Code

Problem B Fox Dividing Cheese
题意:有两个数每次能对他进行一次操作,操作是选取大的一个数对首先(n%2或3或5==0)然后n/=2或3或5,问最后能不能是两个是变成相等的。

思路:很容易想到BFS,有人说数据10e9会不会超时答案是不会的,因为最话情况下是除2。所以复杂度logn不会超时。

代码如下:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <utility>
 9 #include <vector>
10 #include <queue>
11 #include <stack>
12 #define INF 0x7fffffff
13 #define ll long long
14 #define eps 1e-6
15 
16 using namespace std;
17 
18 struct P{
19     int a, b, step;
20 }st;
21 
22 int BFS()
23 {
24     queue<P> q;
25     q.push(st);
26     while(!q.empty()){
27         P vex = q.front();q.pop();
28         P nv;
29         if(vex.a==vex.b) return vex.step;
30         else if(vex.a>vex.b){
31             if(vex.a%2==0){
32                 nv.a = vex.a;
33                 nv.b = vex.b;
34                 nv.step = vex.step+1;
35                 nv.a/=2;
36                 q.push(nv);
37             }
38             if(vex.a%3==0){
39                 nv.a = vex.a;
40                 nv.b = vex.b;
41                 nv.step = vex.step+1;
42                 nv.a/=3;
43                 q.push(nv);
44             }
45             if(vex.a%5==0){
46                 nv.a = vex.a;
47                 nv.b = vex.b;
48                 nv.step = vex.step+1;
49                 nv.a/=5;
50                 q.push(nv);
51             }
52         }
53         else{
54             if(vex.b%2==0){
55                 nv.a = vex.a;
56                 nv.b = vex.b;
57                 nv.step = vex.step+1;
58                 nv.b/=2;
59                 q.push(nv);
60             }
61             if(vex.b%3==0){
62                 nv.a = vex.a;
63                 nv.b = vex.b;
64                 nv.step = vex.step+1;
65                 nv.b/=3;
66                 q.push(nv);
67             }
68             if(vex.b%5==0){
69                 nv.a = vex.a;
70                 nv.b = vex.b;
71                 nv.step = vex.step+1;
72                 nv.b/=5;
73                 q.push(nv);
74             }
75         }
76     }
77     return -1;
78 }
79 
80 int main()
81 {
82 //    freopen("in.txt", "r", stdin);
83 
84     while(scanf("%d%d", &st.a, &st.b)!=EOF){
85         st.step = 0;
86         int ans = BFS();
87         printf("%d
", ans);
88     }
89     return 0;
90 }
View Code

Problem C Hamburgers

题意:让你做汉堡,汉堡有三种原材料组成告诉你汉堡需要什么样的原材料,然后告诉你现在你每种原材料分别有几个,超市里每种原材料的价格,和你有多少钱。超市里原材料无限。

思路:贪心即可,首先统计每种原材料的需要数量(注意可能为零!)然后由于已有的原材料每种不会超过100所以可以算出做几个汉堡(我直接用枚举的),然后在尽量使用剩下的原材料和钱去做。直到钱用完或者原材料用完。若是原材料用完则再把钱用光。

代码如下:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <utility>
 9 #include <vector>
10 #include <queue>
11 #include <stack>
12 #define INF 0x7fffffff
13 #define ll long long
14 #define eps 1e-6
15 
16 using namespace std;
17 
18 ll n[4], p[4], mon, num[4];
19 
20 int main()
21 {
22 //    freopen("in.txt", "r", stdin);
23     char str[110];
24     while(scanf("%s", str)!=EOF){
25         memset(num, 0, sizeof num);
26         for(int i=0; str[i]!=0; i++){
27             if(str[i]=='B')num[0]++;
28             else if(str[i]=='S')num[1]++;
29             else num[2]++;
30         }
31         for(int i=0; i<3; i++){
32             scanf("%I64d", &n[i]);
33         }
34         for(int i=0; i<3; i++){
35             scanf("%I64d", &p[i]);
36         }
37         scanf("%I64d", &mon);
38         for(int i=0; i<3; i++){
39             if(num[i]==0)n[i]=0;
40         }
41         ll ans = 0;
42         ll nn = INF;
43         while(n[0]>=num[0] && n[1]>=num[1] && n[2]>=num[2]){
44             n[0]-=num[0];n[1]-=num[1];n[2]-=num[2];
45             ans++;
46         }
47         if(n[0]+n[1]+n[2]){
48             while(mon>0){
49                 if(n[0]>=num[0])n[0]-=num[0];
50                 else {mon-=(num[0]-n[0])*p[0];n[0] = 0;}
51                 if(n[1]>=num[1])n[1]-=num[1];
52                 else {mon-=(num[1]-n[1])*p[1];n[1] = 0;}
53                 if(n[2]>=num[2])n[2]-=num[2];
54                 else {mon-=(num[2]-n[2])*p[2];n[2] = 0;}
55                 if(mon<0) break;
56                 ans++;
57                 if(n[0]+n[1]+n[2]==0)break;
58             }
59         }
60         ll mm = num[0]*p[0]+num[1]*p[1]+num[2]*p[2];
61         if(mon>=mm)ans+=(mon/mm);
62         printf("%I64d
", ans);
63     }
64 
65     return 0;
66 }
View Code

Problem D Vessels
题意:有若干个碗从上到下,在碗中倒水上面的满了会溢出到下面。初始碗是空的给若干个查询1a b代表向a碗倒b单位水,2 a代表查询a碗水量。

思路:我用的是树状数组+二分(后一个可以倒水的碗)树状数组维护每个碗中的水量。复杂度(Ologn*logm*m)

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <utility>
 8 #include <vector>
 9 #include <queue>
10 #include <stack>
11 #define INF 0x7fffffff
12 #define ll long long
13 #define eps 1e-6
14 #define LEN 200100
15 
16 using namespace std;
17 
18 int n;
19 ll ss[LEN], C[3*LEN], num[LEN];
20 
21 ll lowbit(ll x){return x&-x;}
22 
23 void init(){
24     memset(C, 0, sizeof C);
25     memset(ss, 0 ,sizeof ss);
26 }
27 
28 ll sum(ll x){
29     ll ret = 0;
30     while(x>0){
31         ret+=C[x];x-=lowbit(x);
32     }
33     return ret;
34 }
35 
36 void add(int x,int d){
37     while(x<=n){
38         C[x]+=d;x+=lowbit(x);
39     }
40 }
41 
42 int Bin_S(int l, int r){
43     if(l==r)return l;
44     if(l>r) return -1;
45     int mid = (l+r)/2;
46     if(sum(mid)-sum(l-1)==ss[mid]-ss[l-1])return Bin_S(mid+1, r);
47     else return Bin_S(l, mid);
48 }
49 
50 int main()
51 {
52 //    freopen("in.txt", "r", stdin);
53 
54     while(scanf("%d", &n)!=EOF){
55         init();
56         for(int i=1; i<=n ; i++){
57             scanf("%I64d", &num[i]);
58             ss[i] = ss[i-1]+num[i];
59         }
60         int q, op, a, b;
61         scanf("%d", &q);
62         for(int i=0; i<q; i++){
63             scanf("%d", &op);
64             if(op==1){
65                 scanf("%d%d", &a, &b);
66                 while(b){
67                     int pos, loc;
68                     pos = Bin_S(a, n);
69                     if(pos==-1)break;
70                     loc = sum(pos)-sum(pos-1);
71                     if(num[pos]-loc<b){
72                         b-=(num[pos]-loc);
73                         add(pos, num[pos]-loc);
74                         a = pos+1;
75                         if(a>n)break;
76                     }else{
77                         add(pos, b);
78                         b=0;
79                     }
80                 }
81             }else{
82                 scanf("%d", &a);
83                 printf("%I64d
", sum(a)-sum(a-1));
84             }
85         }
86     }
87     return 0;
88 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3464543.html