Educational Codeforces Round 94 (Rated for Div. 2)

总览


不太常打CF。后来想了想,虽然退休了,还是决定给名字换点颜色。

A. String Similarity

答案字符串可以由(s[1..n])的第(1)位, (s[2..n+1])的第(2)位, (s[3..n+2])的第(3)位...构成。即原字符串的奇数位。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 60;
typedef long long LL;
const int inf = 0x3f3f3f3f;
 
char s[MAXN * 2];
 
int n, t;
int main() {
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        scanf("%s", s);
        for (int i = 0; i < 2*n; i++) {
            if (i%2 == 0) printf("%c", s[i]);
        }
        printf("
");
    }
 
}

B. RPG Protagonist

枚举第一个人取剑的数量,那么第一个人取战斧的数量是可以计算的。第二个人只要贪心从剑和战斧先取重量较小的,再用较大的填满背包即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 60;
typedef long long LL;
const int inf = 0x3f3f3f3f;

int n, t;
int main() {
   scanf("%d", &t);
   while(t--) {
       LL p, f, cnts, cntw, s, w;
       scanf("%lld%lld%lld%lld%lld%lld", &p, &f, &cnts, &cntw, &s, &w);
       LL ans = 0;
       for (LL i = 0; i <= cnts; i++) {
           if (i*s > p) break;
           LL j = min( (p-i*s)/w, cntw );

           LL x, y;
           if (s > w) {
               x = min( f/w, cntw-j );
               y = min( (f - x*w) / s, cnts-i );
           } else {
               y = min( f/s, cnts-i );
               x = min( (f - y*s) / w, cntw-j );
           }
           ans = max(ans, y + x + i + j);
       }
       printf("%lld
", ans);
   }

}

C. Binary String Reconstruction

(0)的两边一定都是(0)。所以可以先遍历处理(0)的位置,标记两边为(0),被标记的地方都看作(1),然后通过剩下的(1)判断是否合法。当1的两边都已经被标记为(0)的时候为不合法。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 100;
typedef long long LL;
const int inf = 0x3f3f3f3f;
 
char s[MAXN];
int v[MAXN];
int n, t, x;
 
bool solve() {
    int len = strlen(s+1);
    
    for (int i = 1; i <= len; i++) v[i] = 1;
 
    for (int i = 1; i <= len; i++) {
        if (s[i] == '0') {
            if (i-x > 0) v[i-x] = 0;
            if (i+x <= len) v[i+x] = 0;
        }
    }
 
    for (int i = 1; i <= len; i++) {
        if (s[i] == '1') {
            int flag = 0;
            if (i-x > 0 && v[i-x] != 0) flag++;
            if (i+x <= len && v[i+x] != 0) flag++;
            if (!flag) return false;
        }
    }
 
    for (int i = 1; i <= len; i++)
        printf("%d", v[i]);
    puts("");
    return true;
 
}
 
int main() {
    scanf("%d", &t);
    while(t--) {
        scanf("%s%d", s+1, &x);
        if (!solve()) printf("-1
");
    }
 
}

D. Zigzags

预处理(sum[i][j]),即前(i)个数中存在的数字(j)的个数。

枚举元组((i,j,k,l))(j)(k)的位置,设为(l)(r)

那么此时满足题意的元组数量即为 (l)前面的(a[r])的个数( * r)后面的(a[l])的个数。更新答案即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3000 + 100;
typedef long long LL;
const int inf = 0x3f3f3f3f;
 
int a[MAXN];
int sum[MAXN][MAXN];
int n, t, x;
 
 
int main() {
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            for (int j = 1; j <= n; j++) sum[i][j] = sum[i-1][j];
            sum[i][a[i]]++;
        }
 
        LL ans = 0;
        for (int i = 1; i <= n; i++)
        for (int j = i+1; j <= n; j++)
            ans += 1ll * sum[i-1][a[j]] * (sum[n][a[i]] - sum[j][a[i]]);
 
        printf("%lld
", ans);
    }
}

E. Clear the Multiset

最优解可能是全都竖着消,或者横着消min次+剩余连通块的处理次数之和。min为数组最小值。

剩余连通块可以递归求解。

写挫了一发。第二发过了。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5000 + 100;
typedef long long LL;
const int inf = 0x3f3f3f3f;

int a[MAXN];
int n, t, x;

int solve(int l, int r, int h) {
    if (l == r) return a[l]-h != 0; //这里直接写return 1结果被hack了。hack数据1 0

    int ans = 0, minX = inf, cnt = 0;
    for (int i = l; i <= r; i++) minX = min(minX, a[i]-h);
    for (int i = l; i <= r; i++) ans += a[i]-h != 0;

    int s = -1, tmp = 0;
    for (int i = l; i <= r; i++) {
        if (s == -1 && a[i]-h > minX) s = i;
        if (s != -1 && (i == r || a[i+1]-h == minX)) {
            tmp += solve(s, i, minX+h);
            s = -1;
        }
    }
    ans = min(ans, minX + tmp);
    return ans;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    printf("%d", solve(1, n, 0));
}

F. x-prime Substrings

too vegetable to solve

G. Mercenaries

too vegetable to solve

原文地址:https://www.cnblogs.com/ruthank/p/13562874.html