Codeforces Round #552 (Div. 3)

本场题目不难,模拟暴力大法好。A~E:模拟+暴力;F:留坑待填;G:埃氏筛+贪心。

A、Restoring Three Numbers

思路:简单数学。

AC代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <complex>
 9 #include <string>
10 #include <vector>
11 #include <set>
12 #include <map>
13 #include <list>
14 #include <deque>
15 #include <queue>
16 #include <stack>
17 #include <bitset>
18 using namespace std;
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
24 const double eps = 1e-6;
25 const double PI = acos(-1.0);
26 const int maxn = 1e5+5;
27 const int inf = 0x3f3f3f3f;
28 
29 
30 LL x[5], a, b, c;
31 
32 int main() {
33     while(cin >> x[1] >> x[2] >> x[3] >> x[4]) {
34         sort(x + 1, x + 5);
35         b = (x[1] - x[2] + x[3]) / 2;
36         c = x[3] - b;
37         a = x[4] - b - c;
38         cout << a << ' ' << b << ' '  << c << endl;
39     }
40     return 0;
41 }
View Code

B、Make Them Equal

思路:暴力+模拟。只需枚举最终的数组变成的数字(1~100)即可。

AC代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <complex>
 9 #include <string>
10 #include <vector>
11 #include <set>
12 #include <map>
13 #include <list>
14 #include <deque>
15 #include <queue>
16 #include <stack>
17 #include <bitset>
18 using namespace std;
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
24 const double eps = 1e-6;
25 const double PI = acos(-1.0);
26 const int maxn = 105;
27 const int inf = 0x3f3f3f3f;
28 
29 
30 int n, ans, now, cha, a[maxn];
31 bool flag;
32 
33 int main() {
34     while(~scanf("%d", &n)) {
35         for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
36         sort(a, a + n);
37         ans = inf;
38         for(int j = 0; j <= 100; ++j) { // 枚举最终数组中所有的元素变为j
39             now = 0, cha = 0; // 注意:cha的初始值为0,因为1~n每个数都可能与j相同
40             for(int k = 0; k < n; ++k) // 找到第一个与j不同的数求差的绝对值cha
41                 if(a[k] != j) {cha = abs(a[k] - j); break;}
42             for(int k = 0; k < n; ++k) { // 模拟即可
43                 if(a[k] < j) {
44                     if(a[k] + cha == j) ++now;
45                     else break;
46                 }
47                 else if(a[k] > j) {
48                     if(a[k] - cha == j) ++now;
49                     else break;
50                 }
51                 else if(a[k] == j) ++now;
52             }
53             if(now == n) ans = min(ans, cha);
54         }
55         if(ans == inf) puts("-1");
56         else printf("%d\n", ans);
57     }
58     return 0;
59 }
View Code

C、Gourmet Cat

思路:数学+暴力。由题易得一周内猫吃肉的种类依次为 a、b、c、a、c、b、a。若 $ a \geq 3 \land b \geq 2 \land c \geq 2 $,则先算出轮数;(否则)剩下的枚举每一天作为起点,简单暴力模拟即可。

AC代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <complex>
 9 #include <string>
10 #include <vector>
11 #include <set>
12 #include <map>
13 #include <list>
14 #include <deque>
15 #include <queue>
16 #include <stack>
17 #include <bitset>
18 using namespace std;
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
24 const double eps = 1e-6;
25 const double PI = acos(-1.0);
26 const int maxn = 105;
27 const int inf = 0x3f3f3f3f;
28 
29 int a, b, c, d, ans, now1, now2, k, dir0[7] = {0, 1, 2, 0, 2, 1, 0}, cnt[3], cnt1[3];
30 
31 int main() {
32     while(cin >> a>> b >> c) {
33         ans = 0;
34         memset(cnt, 0, sizeof(cnt));
35         if(a >= 3 && b >= 2 && c >= 2) {
36             k = min(a / 3, min(b / 2, c / 2));
37             a -= 3 * k, b -= 2 * k, c -= 2 * k;
38             ans = 7 * k;
39         }
40         cnt[0] = a, cnt[1] = b, cnt[2] = c, now2 = 0;
41         for(int i = 0; i < 7; ++i) { // 枚举每一天作为起点
42             cnt1[0] = cnt[0], cnt1[1] = cnt[1], cnt1[2] = cnt[2], now1 = 0;
43             for(int j = i; ; ++j) { // 模拟
44                 if(cnt1[dir0[j % 7]] > 0) --cnt1[dir0[j % 7]], ++now1;
45                 else break;
46             }
47             now2 = max(now1, now2);
48         }
49         cout << ans + now2 << endl;
50     }
51     return 0;
52 }
View Code

D、Walking Robot

思路:简单贪心+模拟。详细思路见代码注释。

AC代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <complex>
 9 #include <string>
10 #include <vector>
11 #include <set>
12 #include <map>
13 #include <list>
14 #include <deque>
15 #include <queue>
16 #include <stack>
17 #include <bitset>
18 using namespace std;
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
24 const double eps = 1e-6;
25 const double PI = acos(-1.0);
26 const int maxn = 2e5+5;
27 const int inf = 0x3f3f3f3f;
28 
29 int n, b, a, x, y, ans, s[maxn];
30 
31 int main() {
32     while(cin >> n >> x >> y) {
33         ans = 0; b = x, a = y;
34         for(int i = 0; i < n; ++i) cin >> s[i];
35         for(int i = 0; i < n; ++i) {
36             if(s[i]) { // 若被光照
37                 if(b) { // 先考虑1个b转换成1个a
38                     if(a + 1 <= y) --b, ++a, ++ans; // 最大不超过y
39                     else if(a) --a, ++ans; // 不能转,则先减去a
40                     else if(b) --b, ++ans; // a为0不能继续减,才看b是否剩余
41                     else break;
42                 }
43                 else if(a) --a, ++ans; // 没有b,则只能减去a
44                 else break; // 没法减则退出
45             }else { // 没有被光照,不能转
46                 if(a) --a, ++ans; // 先考虑a
47                 else if(b) --b, ++ans; // a不能减,再考虑b,因为b的作用遇到光时能产生一个a
48                 else break; // 没法减则退出
49             }
50         }
51         cout << ans << endl;
52     }
53     return 0;
54 }
View Code

E、Two Teams

思路:题意很简单:每次找当前队列中技能最大的学生,向左向右分别连续选择k个学生作为自己的队员。暴力险过。换种思路,用大根堆维护当前序列的最大值,同时标记每个元素分别向前、向后走的第一个位置,暴力模拟即可。

AC代码一:暴力解。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <complex>
 9 #include <string>
10 #include <vector>
11 #include <set>
12 #include <map>
13 #include <list>
14 #include <deque>
15 #include <queue>
16 #include <stack>
17 #include <bitset>
18 using namespace std;
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
24 const double eps = 1e-6;
25 const double PI = acos(-1.0);
26 const int maxn = 2e5+5;
27 const int inf = 0x3f3f3f3f;
28 
29 int n, k, a, ans[maxn], siz, now, cnt, pos, mp[maxn], lt, rt;
30 vector<int> vec;
31 set<int> stl;
32 set<int>::iterator it;
33 
34 int main() {
35     while(~scanf("%d%d", &n, &k)) {
36         memset(ans, 0, sizeof(ans));
37         memset(mp, 0, sizeof(mp));
38         vec.clear();
39         stl.clear();
40         cnt = 0;
41         for(int i = 0; i < n; ++i) {
42             scanf("%d", &a);
43             vec.push_back(a);
44             mp[a] = i;
45             stl.insert(a);
46         }
47         while((siz = stl.size()) != 0) {
48             it = stl.end();
49             --it;
50             ++cnt;
51             if(cnt & 1) now = 1;
52             else now = 2;
53             pos = find(vec.begin(), vec.end(), *it) - vec.begin();
54             lt = max(0, pos - k), rt = min(siz - 1, pos + k);
55             for(int i = lt; i <= rt; ++i) {
56                 ans[mp[vec[i]]] = now;
57                 stl.erase(vec[i]);
58             }
59             vec.erase(vec.begin() + lt, vec.begin() + rt + 1);
60         }
61         for(int i = 0; i < n; ++i) printf("%d", ans[i]);
62         puts("");
63     }
64     return 0;
65 }
View Code

AC代码二:优化解。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <complex>
 9 #include <string>
10 #include <vector>
11 #include <set>
12 #include <map>
13 #include <list>
14 #include <deque>
15 #include <queue>
16 #include <stack>
17 #include <bitset>
18 using namespace std;
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左
22 const int mx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 马可走的八个方向
23 const int my[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
24 const double eps = 1e-6;
25 const double PI = acos(-1.0);
26 const int maxn = 2e5+5;
27 const int inf = 0x3f3f3f3f;
28 
29 int n, k, a, now1, now2, flag, p1, p2, num, ans[maxn], nex[maxn], per[maxn];
30 
31 priority_queue<pair<int, int> > que;
32 bool vis[maxn];
33 
34 
35 int main() {
36     while(~scanf("%d%d", &n, &k)) {
37         while(!que.empty()) que.pop();
38         memset(ans, 0, sizeof(ans));
39         memset(per, 0, sizeof(per));
40         memset(nex, 0, sizeof(nex));
41         flag = 1;
42         memset(vis, false, sizeof(vis));
43         for(int i = 1; i <= n; ++i) {
44             scanf("%d", &a);
45             que.push(make_pair(a, i));
46             per[i] = i - 1;
47             nex[i] = i + 1;
48         }
49         while(!que.empty()) {
50             now1 = que.top().first, now2 = que.top().second, que.pop();
51             if(vis[now2]) continue;
52             vis[now2] = true;
53             flag = !flag;
54             p1 = per[now2], p2 = nex[now2], ans[now2] = flag + 1;
55             num = k;
56             while(num > 0 && p1 > 0) vis[p1] = true, ans[p1] = flag + 1, --num, p1 = per[p1];
57             num = k;
58             while(num > 0 && p2 <= n) vis[p2] = true, ans[p2] = flag + 1, --num, p2 = nex[p2];
59             per[p2] = p1, nex[p1] = p2;
60         }
61         for(int i = 1; i <= n; ++i) printf("%d", ans[i]);
62         puts("");
63     }
64     return 0;
65 }
View Code

猜你喜欢

转载自www.cnblogs.com/acgoto/p/10725576.html