Codeforces Round #620 (Div. 2)

题目链接:https://codeforces.com/contest/1304


A:

白给物理

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 int t;
15 
16 int main() {
17     scanf("%d", &t);
18     while (t--) {
19         ll x, y, a, b; scanf("%lld%lld%lld%lld", &x, &y, &a, &b);
20         if ((y - x) % (a + b) == 0) printf("%lld
", (y - x) / (a + b));
21         else puts("-1");
22     }
23     return 0;
24 }
View Code

B:

由于每个字符串只会出现一次,所以对于每个字符串,首先看它是否回文(暴力check),然后看它reverse之后有没有在之前或之后出现过,如果有就用map存一下。最后遍历一下map就好了。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 110, maxl = 60;
15 string huiwen = "", ans = "";
16 int n, m;
17 set<string>s;
18 map<string, string>mm;
19 
20 bool isHuiwen(string curs) {
21     int p = -1, q = (int)curs.size();
22     while (1) {
23         p++, q--;
24         if (p >= q) break;
25         if (curs[p] != curs[q]) return false;
26     }
27     return true;
28 }
29 
30 int main() {
31     s.clear(), mm.clear();
32     cin >> n >> m;
33     for (int i = 1; i <= n; i++) {
34         string x; cin >> x;
35         s.insert(x);
36     }
37     for (auto i : s) {
38         if (isHuiwen(i)) {
39             if ((int)i.size() > (int)huiwen.size()) huiwen = i;
40             continue;
41         }
42         string tmp = i;
43         reverse(tmp.begin(), tmp.end());
44         if (s.count(tmp)) {
45             s.erase(tmp);
46             mm[i] = tmp;
47         }
48     }
49     stack<string>st;
50     while (!st.empty()) st.pop();
51     for (auto i : mm) {
52         ans += i.first;
53         st.push(i.first);
54     }
55     ans += huiwen;
56     while (!st.empty()) {
57         ans += mm[st.top()];
58         st.pop();
59     }
60     cout << (int)ans.size() << endl << ans << endl;
61     return 0;
62 }
View Code

C:

维护每个时间戳的最高最低温度。设定温度区间一开始为[m,m]。对于新的温度区间,判断之前的温度区间能否从上个时间戳到当前时间戳之内reach到新温度区间即可。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 110;
15 set<int>t;
16 map<int, int>l, h;
17 int q, n, m;
18 
19 int main() {
20     scanf("%d", &q);
21     while (q--) {
22         t.clear(), l.clear(), h.clear();
23         scanf("%d%d", &n, &m);
24         for (int i = 1; i <= n; i++) {
25             int time, low, high;
26             scanf("%d%d%d", &time, &low, &high);
27             t.insert(time);
28             if (!l.count(time)) {
29                 l[time] = low, h[time] = high;
30             } else {
31                 l[time] = max(l[time], low), h[time] = min(h[time], high);
32             }
33         }
34         int flag = 1, lastTime = 0, lastLow = m, lastHigh = m;
35         for (auto currTime : t) {
36             if (l[currTime] > h[currTime]) {
37                 flag = 0;
38                 break;
39             }
40             int deltaTemp = currTime - lastTime, currLow = l[currTime], currHigh = h[currTime];
41             if (lastLow - deltaTemp <= currHigh && lastHigh + deltaTemp >= currLow) {
42                 lastLow = max(currLow, lastLow - deltaTemp);
43                 lastHigh = min(currHigh, lastHigh + deltaTemp);
44                 lastTime = currTime;
45             } else {
46                 flag = 0;
47                 break;
48             }
49         }
50         if (flag) puts("YES"); else puts("NO");
51     }
52     return 0;
53 }
View Code

D:

类似贪心。对于LIS尽量短,把大数字尽量放到前面去;反之把小数字尽量放到前面去。(样例坑人

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 2e5 + 10;
15 int t, n, m, a[maxn], b[maxn];
16 string s;
17 
18 int main() {
19     ios::sync_with_stdio(false);
20     cin.tie(0);
21     cin >> t;
22     while (t--) {
23         cin >> n >> s; m = n;
24         for (int i = 0; i < n; i++) {
25             int len = 1;
26             while (i < s.size() && s[i] == '<') {
27                 len++; i++;
28             }
29             for (int j = i; j > i - len; j--) a[j] = m--;
30         }
31         for (int i = 0; i < n; i++) cout << a[i] << " ";
32         cout << endl;
33         m = 1;
34         for (int i = 0; i < n; i++) {
35             int len = 1;
36             while (i < s.size() && s[i] == '>') {
37                 len++; i++;
38             }
39             for (int j = i; j > i - len; j--) b[j] = m++;
40         }
41         for (int i = 0; i < n; i++) cout << b[i] << " ";
42         cout << endl;
43     }
44     return 0;
45 }
View Code

E:

题意是给定一棵树,q次询问(互相独立),每次询问给定x、y、s、t、k五个数,意思是加上x到y这条边之后,是否存在一条从s到t且长度为k的路径。可以走重复边。

什么情况下合法呢?若s到t路径长度为x,当x<=k且奇偶性相同时则合法。很显然,只要先走到t,然后在t点和它周围的某个点之间反复横跳就行了。

检查也很简单,只要检查三种情况:从s走到t、从s出发先走到x再走到y再走到t、从s出发先走到y再走到x再走到t。

距离用lca即可。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 1e5 + 10;
15 int n, q, f[18][maxn], h[maxn];
16 vector<int>g[maxn];
17 
18 void dfs(int x) {
19     for (int i = 0; i < (int)g[x].size(); i++) {
20         int v = g[x][i];
21         if (v == f[0][x]) continue;
22         f[0][v] = x;
23         h[v] = h[x] + 1;
24         dfs(v);
25     }
26 }
27 
28 int lca(int x, int y) {
29     if (h[x] < h[y]) swap(x, y);
30     for (int i = 17; i >= 0; i--) {
31         if ((h[x] - h[y]) >> i) {
32             x = f[i][x];
33         }
34     }
35     if (x == y) return x;
36     for (int i = 17; i >= 0; i--) {
37         if (f[i][x] != f[i][y]) {
38             x = f[i][x], y = f[i][y];
39         }
40     }
41     return f[0][x];
42 }
43 
44 int dis(int x, int y) {
45     return h[x] + h[y] - h[lca(x, y)] * 2;
46 }
47 
48 bool check(int x, int y) {
49     return y >= x && ((x & 1) == (y & 1));
50 }
51 
52 int main() {
53     ios::sync_with_stdio(false);
54     cin.tie(0);
55     cin >> n;
56     for (int i = 1; i < n; i++) {
57         int x, y; cin >> x >> y;
58         g[x].pb(y), g[y].pb(x);
59     }
60     dfs(1);
61     for (int i = 1; i <= 17; i++) {
62         for (int j = 1; j <= n; j++) {
63             f[i][j] = f[i - 1][f[i - 1][j]];
64         }
65     }
66     cin >> q;
67     while (q--) {
68         int x, y, a, b, k;
69         cin >> x >> y >> a >> b >> k;
70         if (check(dis(a, b), k) || check(dis(a, x) + dis(y, b) + 1, k) || check(dis(a, y) + dis(x, b) + 1, k)) {
71             cout << "YES" << endl;
72         } else {
73             cout << "NO" << endl;
74         }
75     }
76     return 0;
77 }
View Code
原文地址:https://www.cnblogs.com/JHSeng/p/12354803.html