[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 }
Aguin

 

配对

排序扫一遍

#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;
}
Aguin

 

字符串问题

每次尽量多加 二分找位置

 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 }
Aguin

 

公共山峰

复习一下状态细化,就是把走$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 }
Aguin

还有严格按照题意的话可能要考虑只有两个数且相等的情况但是好像没有这种数据来卡我

 

posted @ 2018-06-17 23:17  Aguin  阅读(353)  评论(3编辑  收藏  举报