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

Problem A K-Periodic Array

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

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

代码如下:

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include 
11 #include 
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){
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){
33             if(num[j]==1)_1[j%k]++;
34             if(num[j]==2)_2[j%k]++;
35         }
36         for(int i=0; i){
37             ans+=min(n/k-_1[i], n/k-_2[i]);
38         }
39         printf("%d\n", 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 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include 
11 #include 
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

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\n", ans); 88 } 89 return 0; 90 }

View Code

Problem C Hamburgers

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

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

代码如下:

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include 
11 #include 
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\n", ans);
63     }
64 
65     return 0;
66 }
View Code

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

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

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include 
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){
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\n", sum(a)-sum(a-1));
84             }
85         }
86     }
87     return 0;
88 }
View Code

 

转载于:https://www.cnblogs.com/shu-xiaohao/p/3464543.html

你可能感兴趣的:(Codeforces Round #218 (Div. 2) 解题报告)