本来在快乐写题的,突然A数据炸了,全场重测,unrated……
昨晚的题也有点毒,不过总体来说还算简单。
A:
一开始我也wa on 3了,仔细想想就会发现有重点的情况。
比如n==3, 3 1 2。答案应该是6而不是7。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define fir first 9 #define sec second 10 #define sot(a,b) sort(a+1,a+1+b) 11 #define rep1(i,a,b) for(int i=a;i<=b;++i) 12 #define rep0(i,a,b) for(int i=a;i<b;++i) 13 #define repa(i,a) for(auto &i:a) 14 #define eps 1e-8 15 #define int_inf (1<<30)-1 16 #define ll_inf (1LL<<62)-1 17 #define lson curPos<<1 18 #define rson (curPos<<1)+1 19 /* namespace */ 20 using namespace std; 21 /* header end */ 22 23 int n, last = 0, ans = 0, flag = 1, llast = 0; 24 25 int main() 26 { 27 scanf("%d%d", &n, &last); 28 n--; 29 for (int i = 1; i <= n; i++) 30 { 31 int x; 32 scanf("%d", &x); 33 if (last == 1) 34 { 35 if (x == 1) 36 { 37 flag = 0; 38 } 39 else if (x == 2) 40 { 41 if (llast + last == 4) 42 ans += 2; 43 else 44 ans += 3; 45 } 46 else if (x == 3) 47 ans += 4; 48 } 49 else if (last == 2) 50 { 51 if (x == 2) 52 { 53 ans += 3; 54 } 55 else if (x == 1) 56 ans += 3; 57 else if (x == 3) 58 { 59 flag = 0; 60 } 61 } 62 else if (last == 3) 63 { 64 if (x == 3) 65 { 66 ans += 4; 67 } 68 else if (x == 1) 69 ans += 4; 70 else if (x == 2) 71 { 72 flag = 0; 73 } 74 } 75 if (i >= 1) 76 llast = last; 77 last = x; 78 } 79 if (!flag) 80 puts("Infinite"); 81 else 82 { 83 puts("Finite"); 84 printf("%d ", ans); 85 } 86 return 0; 87 }
B:
各种写法都有。这题可以写得非常短。按字母在字母表的下标奇偶性来分类就好了。
然而我觉得取字母集合,sort一下再next_permutation+剪枝也可以,就是没有分类这种写法优秀。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e2 + 10; 6 7 void print(char *a, int len) 8 { 9 for (int i = 1; i <= len; i++) printf("%c", a[i]); 10 } 11 12 int main() 13 { 14 int t; scanf("%d", &t); 15 while (t--) 16 { 17 char s[maxn], a[maxn], b[maxn]; 18 scanf("%s", s + 1); int len = strlen(s + 1), p = 0, q = 0; 19 sort(s + 1, s + 1 + len); 20 for (int i = 1; i <= len; i++) 21 if (s[i] & 1) a[++p] = s[i]; else b[++q] = s[i]; 22 if (!p || !q) 23 { 24 print(a, p); print(b, q); 25 } 26 else if (abs(a[p] - b[1]) != 1) 27 { 28 print(a, p); print(b, q); 29 } 30 else if (abs(b[q] - a[1]) != 1) 31 { 32 print(b, q); print(a, p); 33 } 34 else printf("No answer"); 35 puts(""); 36 } 37 return 0; 38 }
C:
很容易就想到二分。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define sot(a,b) sort(a+1,a+1+b) 28 #define rep1(i,a,b) for(int i=a;i<=b;++i) 29 #define rep0(i,a,b) for(int i=a;i<b;++i) 30 #define repa(i,a) for(auto &i:a) 31 #define eps 1e-8 32 #define int_inf (1<<30)-1 33 #define ll_inf (1LL<<62)-1 34 #define lson curPos<<1 35 #define rson (curPos<<1)+1 36 /* namespace */ 37 using namespace std; 38 /* header end */ 39 40 const int maxn = 2e5 + 10; 41 int n, z, a[maxn]; 42 43 int main() 44 { 45 scanf("%d%d", &n, &z); 46 for (int i = 0; i < n; i++) scanf("%d", &a[i]); 47 sort(a, a + n); 48 int l = 0, r = n / 2 + 1; 49 while (r - l > 1) 50 { 51 int mid = l + r >> 1, sign = 1; 52 for (int i = 0; i < mid; i++) 53 sign &= (a[n - mid + i] - a[i] >= z); 54 if (sign) l = mid; else r = mid; 55 } 56 printf("%d ", l); 57 return 0; 58 }
D:
有点像是字典树,匹配文法规则为0*1*的字符串。
树上dp,也可以DSU过。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define sot(a,b) sort(a+1,a+1+b) 28 #define rep1(i,a,b) for(int i=a;i<=b;++i) 29 #define rep0(i,a,b) for(int i=a;i<b;++i) 30 #define repa(i,a) for(auto &i:a) 31 #define eps 1e-8 32 #define int_inf 0x3f3f3f3f 33 #define ll_inf 0x7f7f7f7f7f7f7f7f 34 #define lson curPos<<1 35 #define rson curPos<<1|1 36 /* namespace */ 37 using namespace std; 38 /* header end */ 39 40 const int maxn = 2e5 + 10; 41 42 int n, dp[2][maxn]; 43 vector<pair<int, int>> graph[maxn]; 44 ll ans; 45 46 void calc(int u, pair<int, int> v, int mt) 47 { 48 if (!v.second) 49 dp[0][u] += mt * dp[0][v.first]; 50 else 51 dp[1][u] += mt * dp[0][v.first] + mt * dp[1][v.first]; 52 } 53 54 void dfs1(int u, int p) 55 { 56 for (pair<int, int> v : graph[u]) 57 { 58 if (v.first == p) 59 continue; 60 dfs1(v.first, u); 61 calc(u, v, 1); 62 } 63 ans += dp[0][u] + dp[1][u]; 64 dp[0][u]++; 65 } 66 67 void dfs2(int u, int p, int pp1, int pp2) 68 { 69 ans += pp1 + pp2; 70 for (pair<int, int> v : graph[u]) 71 { 72 if (v.first == p) 73 continue; 74 calc(u, v, -1); 75 if (!v.second) 76 dfs2(v.first, u, pp1 + dp[0][u], 0); 77 else 78 dfs2(v.first, u, 0, pp1 + pp2 + dp[0][u] + dp[1][u]); 79 calc(u, v, 1); 80 } 81 } 82 83 int main() 84 { 85 scanf("%d", &n); 86 for (int i = 1, u, v, c; i < n; i++) 87 { 88 scanf("%d%d%d", &u, &v, &c); --u; --v; 89 graph[u].pb(mp(v, c)); 90 graph[v].pb(mp(u, c)); 91 } 92 dfs1(0, -1); dfs2(0, -1, 0, 0); 93 cout << ans << endl; 94 return 0; 95 }
E:
看了rk1大佬的代码才意识到可以二分做。时间复杂度约等于O(NlogN)。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define sot(a,b) sort(a+1,a+1+b) 28 #define rep1(i,a,b) for(int i=a;i<=b;++i) 29 #define rep0(i,a,b) for(int i=a;i<b;++i) 30 #define repa(i,a) for(auto &i:a) 31 #define eps 1e-8 32 #define int_inf (1<<30)-1 33 #define ll_inf (1LL<<62)-1 34 #define lson curPos<<1 35 #define rson (curPos<<1)+1 36 /* namespace */ 37 using namespace std; 38 /* header end */ 39 40 const int maxn = 2e5 + 10; 41 int a[maxn], n; 42 43 ll solve(int l, int r) 44 { 45 if (r - l == 1) return 0; 46 int mid = l + r >> 1; 47 ll ret = solve(l, mid) + solve(mid, r); //避免处理长度为1的区间 48 { 49 set<int>s; 50 //把p当做区间的左端点&&最大值,往右扩展。下法同理。 51 for (int i = mid - 1, j = mid, p = 0; i >= l; i--) 52 { 53 p = max(p, a[i]); 54 while (j < r && a[j] < p) s.insert(a[j++]); 55 ret += s.count(p - a[i]); 56 } 57 } 58 { 59 set<int>s; 60 for (int i = mid, j = mid - 1, p = 0; i < r; i++) 61 { 62 p = max(p, a[i]); 63 while (j >= l && a[j] < p) s.insert(a[j--]); 64 ret += s.count(p - a[i]); 65 } 66 } 67 return ret; 68 } 69 70 int main() 71 { 72 scanf("%d", &n); 73 rep0(i, 0, n) scanf("%d", &a[i]); 74 printf("%lld ", solve(0, n)); 75 return 0; 76 }
F && G:
太神仙了……再见