Loading

Codeforces Round #699 (Div. 2)

A. Space Navigation

大意:

给出一个字符串,代表飞船从原点开始的前进方向,问能否经过删掉几个字符,使得飞船最终能够到达\((x,y)\)

思路:

直接算横纵方向上能达到的最远点即可

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 2e5 + 10;
int n, m, T;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while (T--) {
        cin >> n >> m;
        string s;
        cin >> s;
        int U = 0, D = 0, L = 0, R = 0;
        for (int i = 0; i < s.size(); ++i) {
            if (s[i] == 'R') R++;
            if (s[i] == 'D') D++;
            if (s[i] == 'L') L++;
            if (s[i] == 'U') U++;
        }
        int flg = 1;
        if (n > 0 && R < n) flg = 0;
        if (n < 0 && L < abs(n)) flg = 0;
        if (m > 0 && U < m) flg = 0;
        if (m < 0 && D < abs(m)) flg = 0;
        if (flg)
            cout << "YES\n";
        else
            cout << "NO\n";
    }
    return 0;
}

B. New Colony

大意:

给出一个长度为n的数组,代表n座山的高度h,n和h都在1到100之间

每次都从第一座山推下一个巨石,如果巨石所在的山峰比下一座要矮,那么巨石停留在当前山峰,并使得当前山峰高度+1,否则就一直往下滚,直到滚出n

问第k个巨石停止的位置,如果滚出n就输出-1,k<=1e9

思路:

虽然k很大,但是n和h都很小,所以前面直接暴力模拟即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int t, n, k;
int a[N];
int main() {
    cin >> t;
    while (t--) {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) cin >> a[i];
        int res = -1;
        for (int i = 1; i <= k; i++) {
            res = -1;
            for (int j = 1; j <= n - 1; j++) {
                if (a[j] < a[j + 1]) {
                    a[j]++;
                    res = j;
                    break;
                }
            }
            if (res == -1) break;
        }
        cout << res << endl;
    }
    return 0;
}

C. Fence Painting

大意:

给出两个数组,代表n个篱笆原来的颜色和将要涂成的颜色

现在按顺序前来m个画师,他们都会将任意一个篱笆变成自己代表的颜色

问能否在这m个画师都按顺序完成作画后,使得n个篱笆都会变成要涂的颜色

如果能,输出每个画手画的是哪个篱笆

思路:

首先看有几个篱笆要变色,然后看是否有这么多个画手可以让他变色,而对于不需要的画手,可以直接让他画到最后一个画手要画的位置,然后让最后一个画手涂上颜色即可,所以必须要保证最后一个画手可以画画,也就是b数组中有这个画手代表的颜色

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
int const N = 1e5 + 10;
int n, m, T;
int a[N], b[N], c[N];
map<int, vector<int>> pos;
int f[N];
int ans[N];
int main() {
    cin >> T;
    while (T--) {
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i <= n; i++) cin >> b[i];
        for (int i = 1; i <= m; i++) cin >> c[i];
        for (int i = 1; i <= n; ++i) {
            pos[i].clear();
            f[i] = 0;
        }
        int pos_m = 0;
        for (int i = 1; i <= n; i++) {
            if (b[i] == c[m]) pos_m = i;
            if (a[i] == b[i]) continue;
            pos[b[i]].push_back(i);
            f[b[i]] = i;
        }

        if (f[c[m]] == 0) {
            f[c[m]] = pos_m;

        } else {
            pos[c[m]].pop_back();
        }

        if (f[c[m]] == 0) {
            cout << "No" << endl;
            continue;
        }

        for (int i = 1; i < m; ++i) {
            if (pos[c[i]].size()) {
                ans[i] = pos[c[i]][pos[c[i]].size() - 1];
                pos[c[i]].pop_back();
            } else {
                ans[i] = f[c[m]];
            }
        }
        ans[m] = f[c[m]];
        int flag = 0;
        for (int i = 1; i <= n; ++i) {
            if (pos[i].size()) {
                flag = 1;
            }
        }
        if (flag)
            cout << "No" << endl;
        else {
            cout << "Yes" << endl;
            for (int i = 1; i <= m; i++) {
                cout << ans[i] << " ";
            }
            cout << endl;
        }
    }
    return 0;
}

D. AB Graph

大意:

给出一个完全图,每条边上要么是a要么是b,问能否得到一条路径,使得这条路径上的字符是一个回文串

思路:

首先如果i点和j点之间的两条边相等,都是a或者都是b,那么一定可以组成回文(只需要反复横跳即可)

否则如果m是奇数,那么也一定可以组成回文(假设i到j是a,j到i是b,那么还是反复横跳,得到ababa...)

现在就剩下了m是偶数,那么如果三个点之间的关系如下:

yJyH9P.png

那么一定可以形成回文,因为如果\((m/2)mod2==1\),那么可以从i到j再到k再到j再到i,如此反复,得到aabbaa的形式

否则可以从j到i再到k,得到baab的形式

如果没有这样的关系,那么就相当于一直在ababab的绕圈子,不可能得到回文

#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 5;
typedef long long LL;
int t, n, m;
char mp[N][N];
int main() {
    cin >> t;
    while (t--) {
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cin >> mp[i][j];
            }
        }
        int flag = 0;
        int res1 = 0, res2 = 0, res3 = 0;
        for (int i = 1; i <= n && flag == 0; i++) {
            for (int j = 1; j <= n && flag == 0; j++) {
                if (i == j) continue;
                if (mp[i][j] == mp[j][i]) {
                    res1 = i, res2 = j;
                    flag = 1;
                }
            }
        }
        if (flag) {
            cout << "YES" << endl;
            for (int i = 0; i < m+1; i++) {
                if (i % 2  == 0)
                    cout << res1 << ' ';
                else
                    cout << res2 << ' ';
            }
            cout << endl;
            continue;
        }
        if (m%2) {
            cout << "YES" << endl;
            for (int i = 1; i <= m+1; i++) {
                if (i % 2 == 0)
                    cout << 1 << ' ';
                else
                    cout << 2 << ' ';
            }
            cout << endl;
            continue;
        }

        int flag1, flag2, flag3 = 0;
        for (int i = 1; i <= n && flag3 == 0; i++) {
            flag1 = flag2 = 0;
            res1 = i, res2 = 0, res3 = 0;
            for (int j = 1; j <= n && flag3 == 0; j++) {
                if (i == j) continue;
                if (mp[i][j] == 'b' && mp[j][i] == 'a') flag1 = 1, res2 = j;
                if (mp[i][j] == 'a' && mp[j][i] == 'b') flag2 = 1, res3 = j;
                if (flag1 && flag2) {
                    flag3 = 1;
                }
            }
        }
        if (flag3) {
            cout << "YES" << endl;
            if ((m / 2)  % 2 ) {
                int bb = 1;
                for (int i = 1; i <= m+1; i++) {
                    if (i % 2 ) {
                        if (bb) {
                            cout << res2 << ' ';
                            bb = 0;
                        } else {
                            cout << res3 << ' ';
                            bb = 1;
                        }
                    } else
                        cout << res1 << ' ';
                }
            } else {
                int bb = 1;
                for (int i = 1; i <= m+1; i++) {
                    if (i % 2  == 0) {
                        if (bb) {
                            cout << res2 << ' ';
                            bb = 0;
                        } else {
                            cout << res3 << ' ';
                            bb = 1;
                        }
                    } else
                        cout << res1 << ' ';
                }
            }
            cout << endl;
        }
        else{
            cout << "NO" << endl;
        }
    }
    return 0;
}

E. Sorting Books

大意:

给出n个书的种类,现在需要只能每次选择一本书,然后扔到最后面,问最少多少次操作可以将每个种类的书都放到一块

思路:

首先需要想到应该是留下来的数尽可能多

那么可以处理出每个数出现的区间,那么可以转化为留下不想交的区间,然后使得这些区间中不需要删掉的点最多

这样dp O(n)的算法扫几遍即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int n, a[N], l[N], r[N], cnt[N], ne[N], dp[N];
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (!l[a[i]]) l[a[i]] = i;
        r[a[i]] = i;
    }
    for (int i = n; i >= 1; i--) {
        cnt[a[i]]++;
        ne[i] = max(ne[i + 1], cnt[a[i]]);
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        dp[i] = dp[i - 1];
        if (r[a[i]] == i) dp[i] = max(dp[i], dp[l[a[i]] - 1] + cnt[a[i]]);
        res = max(res, dp[i] + ne[i + 1]);
    }
    cout << n - res << endl;
    return 0;
}

F. AB Tree

大意:

待补

思路:

posted @ 2021-02-06 02:56  dyhaohaoxuexi  阅读(35)  评论(0编辑  收藏  举报