• Codeforces Round #598 (Div. 3)


    比赛链接:传送门

     

    A. Payment Without Change

    代码:

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iomanip>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 100005
    #define M 100005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define upperdiv(a,b) (a/b + (a%b>0))
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
     
    using namespace std;
    typedef long long ll;
    typedef double db;
     
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    template <typename T>
    inline void write(T x) {
        int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x;
        do{++len; c[len] = x%10 + '0';} while (x /= 10);
        for (int i = len; i >= 1; i--) putchar(c[i]);
    }
    template <typename T, typename... Args>
    inline void write(T x, Args ... args) { write(x), write(args...); }
     
    int main() {
        int T;
        cin >> T;
        while (T--) {
            ll a, b, n, S;
            read(a, b, n, S);
            ll cnta = min(a, S/n);
            ll res = S - cnta * n;
            if (res <= b) {
                puts("YES");
            }
            else {
                puts("NO");
            }
        }
        return 0;
    }
    View Code

     

    B. Minimize the Permutation

    暴力。从1到n枚举,每个数尽量地往前和比他大的数交换。并且保证相邻的位置只能换一次。

    交换的时候不考虑两者的大小就会有各种奇奇怪怪的bug。

    代码:O($n^{2}$)

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iomanip>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 105
    #define M 100005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define upperdiv(a,b) (a/b + (a%b>0))
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
     
    using namespace std;
    typedef long long ll;
    typedef double db;
     
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    template <typename T>
    inline void write(T x) {
        int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x;
        do{++len; c[len] = x%10 + '0';} while (x /= 10);
        for (int i = len; i >= 1; i--) putchar(c[i]);
    }
    template <typename T, typename... Args>
    inline void write(T x, Args ... args) { write(x), write(args...); }
     
    int a[N];
    int main() {
        int T;
        cin >> T;
        while (T--) {
            int n; read(n);
            for (int i = 1; i <= n; i++) {
                read(a[i]);
            }
            int st = 1;
            for (int i = 1; i <= n; i++) {
                for (int j = st; j <= n; j++) {
                    if (a[j] == i) {
                        for (int k = j-1; k >= st; k--) {
                            if (a[k] > a[k+1])
                                swap(a[k], a[k+1]);
                            else {
                                break;
                            }
                        }
                        st = max(j, i+1);
                    }
                }
            }
     
            for (int i = 1; i <= n; i++) {
                printf("%d%c", a[i], " 
    "[i==n]);
            }
        }
        return 0;
    }
    /*
    4
    4
    1 2 4 3
    5
    5 4 1 3 2
    1
    1
    4
    4 3 2 1
    */
    View Code

     

    C. Platforms Jumping(贪心)

    从前到后,贪心地在两岸和木板之间、木板和木板之间插入长度为d-1的“水”,直到“水”的总长度+木板的总长度 = n。

    如果“水”的数量超过m+1就是非法的。

    否则就得到了一个方案。

    代码:O(n)

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iomanip>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 1005
    #define M 1005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define upperdiv(a,b) (a/b + (a%b>0))
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
     
    using namespace std;
    typedef long long ll;
    typedef double db;
     
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    template <typename T>
    inline void write(T x) {
        int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x;
        do{++len; c[len] = x%10 + '0';} while (x /= 10);
        for (int i = len; i >= 1; i--) putchar(c[i]);
    }
    template <typename T, typename... Args>
    inline void write(T x, Args ... args) { write(x), write(args...); }
     
    int c[M];
    int ans[N];
    vector <int> gaps;
    int main() {
        int n, m, d;
        read(n, m, d);
        int sum = 0;
        for (int i = 1; i <= m; i++) {
            read(c[i]);
            sum += c[i];
        }
        int r = sum;
        while (r < n) {
            if (r + d-1 <= n) {
                gaps.push_back(d-1);
                r += d-1;
            }
            else {
                gaps.push_back(n - r);
                r = n;
            }
            if (sz(gaps) > m+1)
                break;
        }
        if (sz(gaps) > m+1) {
            return puts("NO"), 0;
        }
        else {
            puts("YES");
            int idgap = 0, idc = 1;
            for (int i = 1; i <= n;) {
                if (idgap < sz(gaps)) {
                    for (int j = 0; j < gaps[idgap]; j++) {
                        ans[i++] = 0;
                    }
                    idgap++;
                }
                for (int j = 0; j < c[idc]; j++) {
                    ans[i++] = idc;
                }
                idc++;
            }
            for (int i = 1; i <= n; i++) {
                printf("%d%c", ans[i], " 
    "[i==n]);
            }
        }
        return 0;
    }
    View Code

     

    D. Binary String Minimizing(贪心+双指针)

    从左到右每个0依次和当前最左边的1交换,消耗这两个数下标之差的交换次数。

    如果次数不够用,就让这个0和最远的能交换的1交换位置。

    代码:O(n)

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iomanip>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 100005
    #define M 100005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define upperdiv(a,b) (a/b + (a%b>0))
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
     
    using namespace std;
    typedef long long ll;
    typedef double db;
     
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    template <typename T>
    inline void write(T x) {
        int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x;
        do{++len; c[len] = x%10 + '0';} while (x /= 10);
        for (int i = len; i >= 1; i--) putchar(c[i]);
    }
    template <typename T, typename... Args>
    inline void write(T x, Args ... args) { write(x), write(args...); }
     
    int main() {
        int q; cin >> q;
        while (q--) {
            ll n, k; read(n, k);
            string s; cin >> s;
            int st1 = 0;
            ll resk = k;
            while (st1 < n && s[st1] == '0')
                st1++;
            for (int i = st1; i < n; i++) {
                if (s[i] == '0') {
                    if (i - st1 <= resk) {
                        resk -= i - st1;
                        swap(s[i], s[st1]);
                        st1++;
                    }
                    else {
                        swap(s[i], s[i - resk]);
                        resk = 0;
                        break;
                    }
                }
            }
            cout << s << endl;
        }
        return 0;
    }
    View Code

     

    E. Yet Another Division Into Teams(dp+转移路径)

    让能力相近的选手组队是最好的。

    组成人数x >= 6人的队伍不如把能力最大的3人提出来组成1个3人队+1个x-3人队,所以只用考虑3、4、5人的队伍。

    对数组a排序后,设$f_{i}$表示前i个人组完队后得到的最小的total diversity。

    对每个i考虑$f_{i}从f_{i-3}、f_{i-4}、f_{i-5}$转移,因为数组a已经排过序了,i-j产生的diversity就是a[i] - a[i-j+1]。

    记录转移时的前驱。最后相同区间内的人都分到同一组。

    代码:O(n)

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iomanip>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 200005
    #define M 100005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define upperdiv(a,b) (a/b + (a%b>0))
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    template <typename T>
    inline void write(T x) {
        int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x;
        do{++len; c[len] = x%10 + '0';} while (x /= 10);
        for (int i = len; i >= 1; i--) putchar(c[i]);
    }
    template <typename T, typename... Args>
    inline void write(T x, Args ... args) { write(x), write(args...); }
    
    struct Node{
        ll val;
        int id;
        bool operator < (const Node& x) const {
            return val < x.val;
        }
    }a[N];
    ll sum[N];
    ll f[N];
    int pre[N];
    int ans[N];
    int main() {
        int n; read(n);
        sum[0] = 0;
        for (int i = 1; i <= n; i++)
            read(a[i].val),
            a[i].id = i,
            sum[i] = sum[i-1] + a[i].val;
        sort(a+1, a+1+n);
        memset(f, 0x3f, sizeof f);
        f[0] = 0;
        pre[0] = -1;
        for (int i = 3; i <= n; i++) {
            for (int j = 3; j <= 5; j++) {
                if (i-j >= 0 && f[i] > f[i-j] + a[i].val - a[i-j+1].val) {
                    f[i] = f[i-j] + a[i].val - a[i-j+1].val;
                    pre[i] = i-j;
                }
            }
        }
        int tot = 0;
        for (int i = n; i >= 1; i = pre[i]) {
            ++tot;
            for (int j = i; j > pre[i]; j--) {
                ans[a[j].id] = tot;
            }
        }
        cout << f[n] << ' ' << tot << endl;
        for (int i = 1; i <= n; i++) {
            printf("%d%c", ans[i], " 
    "[i == n]);
        }
        return 0;
    }
    View Code

     

    F. Equalizing Two Strings(逆序对)

    因为交换次数任意,所以len > 2的操作都可以看作若干次len = 2的操作的叠加。不妨只考虑len = 2的操作。

    ①:如果字母构成不同一定不行。

    ②:如果字母构成相同,并且至少有一个字母重复出现,一定可行。可以先把s中两个相同的字母换到最左边,然后s中选择区间[1,2]时,t串中任意相邻的两个字母可以无限交换。

    ③:如果字母构成相同,并且没有重复字母。在s中选择一个len = 2的区间,再在t中选择一个len = 2的区间,就相当于在t中选择两个len = 2的区间。

        那么只要t能在偶数次len = 2的操作中得到s,就可行,否则就不可行。(此时t长度最多26,冒泡排序就行)

    代码:O(n + $26^{2}$)

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iomanip>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 100005
    #define M 100005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define upperdiv(a,b) (a/b + (a%b>0))
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    template <typename T>
    inline void write(T x) {
        int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x;
        do{++len; c[len] = x%10 + '0';} while (x /= 10);
        for (int i = len; i >= 1; i--) putchar(c[i]);
    }
    template <typename T, typename... Args>
    inline void write(T x, Args ... args) { write(x), write(args...); }
    
    int n;
    string s, t;
    int cnts[30], cntt[30];
    bool solve() {
        for (int i = 0; i < 26; i++) {
            if (cnts[i] != cntt[i])
                return false;
        }
        for (int i = 0; i < 26; i++) {
            if (cnts[i] > 1)
                return true;
        }
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                if (t[j] == s[i]) {
                    for (int k = j-1; k >= i; k--) {
                        swap(t[k+1], t[k]);
                        cnt++;
                    }
                }
            }
        }
        return cnt % 2 == 0;
    }
    int main() {
        int q; cin >> q;
        while (q--) {
            cin >> n;
            cin >> s >> t;
            memset(cnts, 0, sizeof cnts);
            memset(cntt, 0, sizeof cntt);
            for (int i = 0; i < n; i++) {
                cnts[s[i]-'a']++;
                cntt[t[i]-'a']++;
            }
            bool ans = solve();
            if (ans)
                puts("YES");
            else
                puts("NO");
        }
        return 0;
    }
    View Code

     

     

  • 相关阅读:
    android自定义通知栏遇到的问题
    写博客号的初衷
    模型转换遇关键字
    界面传值的四种方式
    button循环添加事件
    解析数据的步骤
    数组排序 (数组是有序容器,因此集合中只有数组才能排序。)
    集合遍历
    自定义view和自定义cell
    cell自适应高度
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/11797744.html
Copyright © 2020-2023  润新知