AtCoder Grand Contest 039

A.给你一个字符串 复制K-1次首尾相接 每次你可以把任意位置的字符替换成任意一个 问你最少替换几次可以使得复制后的串任意两个相邻的字符不同

解:一段长度为x的相同字符 要满足条件需要x/2次替换

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
        string a;
        cin >> a;
        ll k;
        cin >> k;
        int len = a.size();
        if (len == 1) {
                cout << k / 2 << endl;
        } else if (len == 2) {
                if (a[0] == a[1]) {
                        cout << k << endl;
                } else {
                        cout << 0 << endl;
                }
        } else {
                bool flg = 1;
                for (int i = 1; i < len; i++) {
                        if (a[i] != a[0]) {
                                flg = 0;
                                break;
                        }
                }
                if (flg) {
                        cout << 1LL * len * k / 2 << endl;
                        return 0;
                }
                ll ans = 0;
                char ch = '0';
                int now = 0;
                for (int i = 0; i <= len; i++) {
                        if (i == len || a[i] != ch) {
                                ans += now / 2;
                                ch = a[i];
                                now = 1;
                                continue;
                        }
                        now++;
                }
                int l = 0, r = 0;
                if (a[0] == a[len - 1]) {
                        for (l = 0; l < len; l++)
                                if (a[l] != a[0]) {
                                        l--;
                                        break;
                                }
                        for (r = len - 1; r >= 0; r--)
                                if (a[r] != a[0]) {
                                        r++;
                                        break;
                                }
                        r = len - r;
                        l++;
                        ans -= l / 2 + r / 2;
                }
                ans *= k;
                ans += 1LL * (l + r) / 2 * (k - 1);
                ans += l / 2 + r / 2;
                cout << ans << endl;
        }
}
View Code

B.给你一个连通图 问你最多能把这个图分成几层(同层之间的点不能有边 类似于X分图)

解:直接暴力从每个点开始BFS即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> g[205];
char f[205];
int du[205];
int lev[205];
bool vis[205];
int main() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
                scanf("%s", f + 1);
                for (int j = i + 1; j <= n; j++) {
                        if (f[j] == '1') {
                                g[i].push_back(j);
                                g[j].push_back(i);
                                du[i]++, du[j]++;
                        }
                }
        }
        queue<int> que;
        bool flag = 1;
        int ans = -1;
        for (int i = 1; i <= n; i++) {
                //cout << "do " << i << endl;
                fill_n(lev, n + 2, 0);
                fill_n(vis, n + 2, 0);
                flag = 1;
                int ansnow = -1;
                while (que.size()) {
                        que.pop();
                }
                que.push(i);
                lev[i] = 1;
                while (que.size() && flag) {
                        int x = que.front();
                        //cout << x << " " << lev[x] << endl;
                        que.pop();
                        vis[x] = 1;
                        for (int v : g[x]) {
                                if (lev[v] == 0) {
                                        lev[v] = lev[x] + 1;
                                        ansnow = max(ansnow, lev[v]);
                                        que.push(v);
                                } else if (lev[v] == lev[x] || abs(lev[v] - lev[x]) >= 2) {
                                        flag = 0;
                                        break;
                                } else if (abs(lev[v] - lev[x]) == 1) {
                                        if (lev[v] < lev[x] && !vis[v]) {
                                                flag = 0;
                                                break;
                                        }
                                        if (lev[v] > lev[x] && vis[v]) {
                                                flag = 0;
                                                break;
                                        }
                                }
                        }
                }
                if (flag) {
                        ans = max(ans, ansnow);
                }
        }
        cout << ans << endl;
}
View Code

posted @ 2019-10-28 23:01  Aragaki  阅读(198)  评论(0编辑  收藏  举报