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\n", (y - x) / (a + b)); 21 else puts("-1"); 22 } 23 return 0; 24 }
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 }
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 }
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 }
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 }