[Offer收割]编程练习赛64
判断异或和是否为0
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() { 5 int n, sum = 0, x; 6 scanf("%d", &n); 7 for(int i = 1; i <= n; ++i) scanf("%d", &x), sum ^= x; 8 if(sum) puts("0"); 9 else printf("%lld\n", (1LL << n) - 2); 10 return 0; 11 }
排序扫一遍
#include <bits/stdc++.h> using namespace std; typedef long long LL; int A[22], B[22]; int main() { int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", A + i); for(int i = 1; i <= n; ++i) scanf("%d", B + i); sort(A + 1, A + 1 + n); sort(B + 1, B + 1 + n); LL ans = 1, p = 0; for(int i = 1; i <= n; ++i) { while(p < n && A[p+1] <= B[i]) ++p; ans *= (p - i + 1); } printf("%lld\n", ans); return 0; }
每次尽量多加 二分找位置
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5 + 10; 4 vector<int> nxt[26], add[26]; 5 char s[maxn]; 6 7 int main() { 8 scanf("%s", s + 1); 9 int len = strlen(s + 1), ans = 0, o = 0; 10 while(o < len) { 11 ans++; 12 int p = 0; 13 while(o < len) { 14 int x = s[o+1] - 'a'; 15 int np = upper_bound(nxt[x].begin(), nxt[x].end(), p) - nxt[x].begin(); 16 if(np == nxt[x].size()) break; 17 o++, p = nxt[x][np], add[x].push_back(o); 18 } 19 if(p == 0) o++, add[s[o]-'a'].push_back(o); 20 for(int i = 0; i < 26; ++i) { 21 for(int j = 0; j < add[i].size(); ++j) nxt[i].push_back(add[i][j]); 22 add[i].clear(); 23 } 24 } 25 printf("%d\n", ans); 26 return 0; 27 }
复习一下状态细化,就是把走$i$和走$j$分成两步走
$f[i][j][0/1][0/1]$表示考虑到($i$,$j$)位置,最后一段递增/递减,最后一步走的是$j$/$i$的最大值
当满足$x[i] = y[j]$时,有$f[i][j][0][0] = \max \limits_{0 \leq k \leq j - 1} \{ f[i][k][0][1] \}$, 这个前缀最大值可以用一个滚动数组维护
类似的,当满足$x[i] > y[j]$时,有$f[i][j][0][1] = \max \limits_{0 \leq k \leq i - 1} \{ f[k][j][1][0] \}$
还有两种转移也是一样的
注意初始化的情况
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2005; 4 int f[maxn][maxn][2][2]; 5 int MX[maxn][2], MY[maxn][2]; 6 int x[maxn], y[maxn]; 7 8 int main() { 9 int nx, ny, ans = 0; 10 scanf("%d", &nx); 11 for(int i = 1; i <= nx; ++i) scanf("%d", x + i); 12 scanf("%d", &ny); 13 for(int i = 1; i <= ny; ++i) scanf("%d", y + i); 14 for(int i = 1; i <= nx; ++i) { 15 for(int j = 1; j <= ny; ++j) { 16 if(x[i] == y[j]) f[i][j][0][0] = max(1, MX[i][0]); 17 if(x[i] > y[j]) f[i][j][0][1] = MY[j][1] + 1; 18 if(x[i] == y[j]) f[i][j][1][0] = max(1, MX[i][1]); 19 if(x[i] < y[j]) f[i][j][1][1] = MY[j][0] + 1; 20 MX[i][0] = max(MX[i][0], f[i][j][0][1]); 21 MX[i][1] = max(MX[i][1], f[i][j][1][1]); 22 MY[j][0] = max(MY[j][0], f[i][j][0][0]); 23 MY[j][1] = max(MY[j][1], f[i][j][1][0]); 24 ans = max(ans, max(f[i][j][1][0], f[i][j][0][0])); 25 } 26 } 27 printf("%d\n", ans); 28 return 0; 29 }
还有严格按照题意的话可能要考虑只有两个数且相等的情况但是好像没有这种数据来卡我