Codeforces Round #316 (Div. 2)(ABCD)

A

题意:

每行代表一个城市每列的选举人的投票,投票最多的表明该城市支持他,如果支持的人数相同,则选小的,求获得最多城市支持的人。

解析:

直接模拟就好了。

my code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 105;
int candid[N], winer[N];
int a[N];
int n, m;
int main() {
    int val;
    while(scanf("%d%d", &n, &m) != EOF) {

        memset(winer, 0, sizeof(winer));

        for(int i = 1; i <= m; i++) {

            memset(candid, 0, sizeof(candid));
            for(int i = 1; i <= n; i++) {
                scanf("%d", &val);
                candid[i] += val;
            }

            int maxv = -INF, maxp = 0;
            for(int i = 1; i <= n; i++) {
                if(candid[i] > maxv) {
                    maxv = candid[i];
                    maxp = i;
                }
            }

            winer[maxp]++;
        }

        int maxv = -INF, maxp = 0;
        for(int i = 1; i <= n; i++) {
            if(winer[i] > maxv) {
                maxv = winer[i];
                maxp = i;
            }
        }
        printf("%d\n", maxp);
    }
    return 0;
}

B

题意:

知道总共可以选的数,和Misha选的数,求Andrew选一个能让尽可能多的数到Andrew的距离比Misha更近。

解析:

我们再数轴上来看:
显然,如果m到n的长度比1到m大很多,andrew选择m+1至少右边所有的他都能比misha近。
同理,如果左边比右边长,那么就选m-1这个点。
如果左边和右边相等,题目要求说If there are multiple such values, print the minimum of them.要求我们打印小的,也就是m-1。
特别的,当n=1的时候,只能选择数1,所以输出1。

my code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int n, m;
int main() {
    while(scanf("%d%d", &n, &m) != EOF) {
        int left = m - 1, right = n - m;
        if(left < right) {
            printf("%d\n", min(m+1, n));
        }else {
            printf("%d\n", max(m-1, 1));
        }
    }
    return 0;
}

C

给你一个字符串带有点的,连续的两个点可以变成一个点。
f(s) 操作是说连续把两个点变成一个点最少操作
然后有m次询问,每次把x位置上的字符变成c,先变完,再询问每次的 f(s)

解析:

先扫一遍整个字符串,如果发现连续两个”.”的情况,答案就加一,然后对每次询问中的替换:如果由小写字母换成小写字母或者由”.”换成”.”则显然不影响答案,如果是由字母替换成”.”,则查询该位置左右的字符,如果有一个”.”说明这次更改使得答案增加了一,左右侧都有”.”则答案加二
同样的道理,如果替换是由”.”换成字母,同样查询左右位置的字符,如果是”.”则答案减一,道理同上。

my code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = (int)3e5 + 10;
char str[MAXN];
int n, m;
int main() {
    while(scanf("%d%d", &n, &m) != EOF) {
        scanf("%s", str+1);
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            if(str[i] == '.' && str[i+1] == '.')
                ans++;
        }

        int x;
        char c[5];
        while(m--) {
            scanf("%d%s", &x, c);
            if(c[0] == '.') {
                if(str[x] != '.') {
                    if(x + 1 <= n && str[x+1] == '.')
                        ans++;
                    if(x - 1 > 0 && str[x-1] == '.')
                        ans++;
                }
                str[x] = c[0];
                printf("%d\n", ans);
            }else {
                if(str[x] == '.') {
                    if(x + 1 <= n && str[x+1] == '.')
                        ans--;
                    if(x - 1 > 0 && str[x-1] == '.')
                        ans--;
                }
                str[x] = c[0];
                printf("%d\n", ans);
            }
        }
    }
    return 0;
}

D

题意:

给你一个树形的图,先输入的是每个孩子所指向的父亲节点的编号,
然后询问的是,以v为根,深度为h的子树节点,能否构成回文串。

解析:

26个字母看成一个二进制位,如果最后二进制位1个数>=2就不是回文了,由于要计算子树,可以这样处理,pre[d] 数组存的是当前这一层d所有的异或和,dfs进去之前,先计算一下前缀和,进去之后,再计算一次异或和,这样两次异或的前缀会被抵消掉,就相当于是求子树的异或和状态了。

my code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define pb push_back
using namespace std;
const int N = 500005;

vector<int> G[N], Q[N];
int h[N];

int res[N], pre[N];
char str[N];
int n, m;

void init() {
    memset(res, 0, sizeof(res));
    for(int i = 1; i <= n; i++) {
        G[i].clear(), Q[i].clear();
    }
}

void dfs(int u, int de) {
    for(int i = 0; i < Q[u].size(); i++) {
        int id = Q[u][i];
        res[id] ^= pre[h[id]];
    }
    for(int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        dfs(v, de+1);
    }
    pre[de] ^= (1<<(str[u] - 'a'));
    for(int i = 0; i < Q[u].size(); i++) {
        int id = Q[u][i];
        res[id] ^= pre[h[id]];
    }
}

bool judge(int num) {
    if(num == 0) return true;
    int cnt = 0;
    while(num) {
        if(num & 1) cnt++;
        num >>= 1;
    }
    return cnt == 1;
}

int main() {
    while(scanf("%d%d", &n, &m) != EOF) {
        init();
        int fa;
        for(int i = 2; i <= n; i++) {
            scanf("%d", &fa);
            G[fa].pb(i);
        }
        scanf("%s", str+1);
        int V, H;
        for(int i = 1; i <= m; i++) {
            scanf("%d%d", &V, &H);
            Q[V].pb(i);
            h[i] = H;
        }
        dfs(1, 1);
        for(int i = 1; i <= m; i++) {
            puts(judge(res[i]) ? "Yes" : "No");
        }
    }
    return 0;
}

你可能感兴趣的:(codeforces)