暑假集训——cf热身赛部分题有感加其题解

刚刚开始集训,集训队队长暂时还没有拉专题,而是拉了部分codeforces上过题人数在2000左右的题组成了一场热身赛(其实就是一场练习),花了一天时间终于把它刷完了,其中很多题让我学到了很多骚操作,还有题是问了学长才会的,自己真的是太菜了!

题目链接:http://codeforces.com/contest/879/problem/C

题目:

题意:对于任意的一个数x,进行题目给的n种位运算,得到一个新数y,然后让你进行压缩,只进行k次位运算操作(0<=k<=5),也能将x变成y,y的范围为0~1023。

思路:这题需要对位运算十分熟悉,然而我对二进制的了解只是入门,最后还是学长和我说的这题怎么做才A的。应为对于每一个数进行与、或、异或只会对它的二进制进行操作,那么只要最后得到的结果的二进制和题目给的那些操作得到的数的二进制一致,因此只需判断它的每个进位从什么变成了什么即可,最后输出一个总的或的数,异或的数,与的数。因此我们拿两个数,一个二进制全为0(0),一个全是1(1023)进行对比即可确定某个进位进行了哪种操作。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 typedef long long ll;
17 typedef unsigned long long ull;
18 
19 #define bug printf("*********\n");
20 #define debug(x) cout <<"[" <<x <<"]" <<end;
21 #define IO ios::sync_with_stdio(false),cin.tie(0);
22 
23 
24 const int maxn = 1e5 + 7;
25 const double pi = acos(-1);
26 const int inf = 0x3f3f3f3f;
27 const ll INF = 0x3f3f3f3f3f3f3f3f;
28 
29 int n, x;
30 char s[3];
31 
32 int main() {
33     scanf("%d", &n);
34     int cnt1 = 0, cnt2 = 1023;
35     while(n--) {
36         scanf("%s%d", s, &x);
37         if(s[0] == '^') {
38             cnt1 ^= x;
39             cnt2 ^= x;
40         } else if(s[0] == '&') {
41             cnt1 &= x;
42             cnt2 &= x;
43         } else {
44             cnt1 |= x;
45             cnt2 |= x;
46         }
47     }
48     int AND = 0, OR = 0, XOR = 0;
49     int tmp = 1;
50     for(int i = 0; i < 10; i++) {
51         int num1 = cnt1 & 1, num2 = cnt2 & 1;
52         if(num1 == 0) {
53             if(num2 == 1) {
54                 AND += tmp;
55             }
56         } else {
57             if(num2 == 0) {
58                 XOR += tmp;
59                 AND += tmp;
60             } else {
61                 OR += tmp;
62                 AND += tmp;
63             }
64         }
65         cnt1 >>= 1, cnt2 >>= 1;
66         tmp <<= 1;
67     }
68     printf("3\n& %d\n| %d\n^ %d\n", AND, OR, XOR);
69     return 0;
70 }
View Code

题目链接:http://codeforces.com/contest/864/problem/C

题目:

题意:一辆车在一条长为a的路上开k趟(来算一趟,回去一趟),车可以装b升油(每跑一千米消耗一升),在距离起点f米出有一个加油站,问你最少需要加多少次油。

思路:模拟即可,感觉自己模拟好差,这题WA了2发才A,一开始还以为是规律题,打扰了~

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 typedef long long ll;
17 typedef unsigned long long ull;
18 
19 #define bug printf("*********\n");
20 #define FIN freopen("in.txt", "r", stdin);
21 #define debug(x) cout <<"[" <<x <<"]" <<end;
22 #define IO ios::sync_with_stdio(false),cin.tie(0);
23 
24 
25 const int maxn = 1e5 + 7;
26 const double pi = acos(-1);
27 const int inf = 0x3f3f3f3f;
28 const ll INF = 0x3f3f3f3f3f3f3f3f;
29 
30 ll a, d, f, k, ans;
31 
32 int main() {
33     scanf("%lld%lld%lld%lld", &a, &d, &f, &k);
34     ll t = d;
35     for(ll i = 1; i <= k; i++) {
36         if(i & 1) {
37             if(t < f) {
38                 puts("-1");
39                 return 0;
40             }
41             t -= f;
42             if(i == k) {
43                 if(t >= a - f) {
44                     printf("%lld\n", ans);
45                     return 0;
46                 } else {
47                     if(d < a - f) {
48                         puts("-1");
49                         return 0;
50                     } else {
51                         ans++;
52                         t = d;
53                     }
54                 }
55             } else {
56                 if(t >= 2 * (a - f)) continue;
57                 else {
58                     if(d < 2 * (a - f)) {
59                         puts("-1");
60                         return 0;
61                     } else {
62                         ans++;
63                         t = d;
64                     }
65                 }
66             }
67         } else {
68             if(t < 2 * (a - f)) {
69                 puts("-1");
70                 return 0;
71             }
72             t -= 2 * (a - f);
73             if(i == k) {
74                 if(t >= f) {
75                     printf("%lld\n", ans);
76                     return 0;
77                 } else {
78                     ans++;
79                     t = d;
80                 }
81             } else {
82                 if(t < 2 * f)  {
83                     if(d < 2 * f) {
84                         puts("-1");
85                         return 0;
86                     } else {
87                         ans++;
88                         t = d;
89                     }
90                 }
91                 t -= f;
92             }
93         }
94 //        printf("%lld %lld\n", i, ans);
95     }
96     printf("%lld\n", ans);
97     return 0;
98 }
View Code

题目链接:http://codeforces.com/contest/864/problem/E

题目:

题意:房子发生着火,里面有N件物品,每件物品救出来需要t的时间,它在d分钟后销毁,价值为p,问你能救出来的物品的总价值为多少,并按顺序打印救的顺序。

思路:01背包+打印路径,dp[i][j]表示第i件物品在第j时被救出来,用vis标记表示第i件物品在j时有没有被救出来,然后用一个vector反转打印路径。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 typedef long long ll;
17 typedef unsigned long long ull;
18 
19 #define bug printf("*********\n");
20 #define FIN freopen("in.txt", "r", stdin);
21 #define debug(x) cout <<"[" <<x <<"]" <<end;
22 #define IO ios::sync_with_stdio(false),cin.tie(0);
23 
24 
25 const int maxn = 1e2 + 7;
26 const double pi = acos(-1);
27 const int inf = 0x3f3f3f3f;
28 const ll INF = 0x3f3f3f3f3f3f3f3f;
29 
30 int n, ans, k, mx, t;
31 int dp[maxn][2007], vis[maxn][2007];
32 vector<int> v;
33 
34 struct node {
35     int t, d, p, id;
36     bool operator < (const node& x) const {
37         return d < x.d;
38     }
39 }a[maxn];
40 
41 int main() {
42     cin >>n;
43     for(int i = 1; i <= n; i++) {
44         cin >>a[i].t >>a[i].d >>a[i].p;
45         a[i].id = i;
46         mx = max(mx, a[i].d);
47     }
48     sort(a + 1, a + n + 1);
49     for(int i = 1; i <= n; i++) {
50         for(int j = 0; j <= mx; j++) {
51             dp[i][j] = dp[i-1][j];
52             if(j >= a[i].t && j < a[i].d) {
53                 if(dp[i-1][j-a[i].t] + a[i].p > dp[i][j]) {
54                     dp[i][j] = dp[i-1][j-a[i].t] + a[i].p;
55                     vis[i][j] = 1;
56                 }
57             }
58         }
59     }
60     for(int i = 0; i <= mx; i++) {
61         if(dp[n][i] > ans) {
62             ans = dp[n][i];
63             t = i;
64         }
65     }
66     for(int i = n; i >= 1; i--) {
67         if(vis[i][t]) {
68             v.push_back(a[i].id);
69             t = t - a[i].t;
70         }
71     }
72     cout <<ans <<endl;
73     cout <<v.size() <<endl;
74     reverse(v.begin(), v.end());
75     for(int i = 0; i < v.size(); i++) {
76         cout <<v[i] <<" ";
77     }
78     cout <<endl;
79     return 0;
80 }
View Code

猜你喜欢

转载自www.cnblogs.com/Dillonh/p/9327932.html