zoukankan      html  css  js  c++  java
  • Codeforces Round #648 (Div. 2)

    传送门
    视频题解

    A. Matrix Game

    简单博弈(贪心?)。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/7 22:39:24
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n, m; cin >> n >> m;
        vector <vector <int>> a(n, vector <int>(m));
        vector <int> cols(m), rows(n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cin >> a[i][j];
                if (a[i][j]) {
                    ++cols[j];
                    ++rows[i];
                }
            }
        }
        int cntr = 0, cntl = 0;
        for (int i = 0; i < n; i++) {
            if (rows[i] == 0) ++cntr;
        }
        for (int i = 0; i < m; i++) {
            if (cols[i] == 0) ++cntl;
        }
        int t = min(cntr, cntl);
        if (t & 1) {
            cout << "Ashish" << '
    ';
        } else {
            cout << "Vivek" << '
    ';
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    B. Trouble Sort

    注意到(b)中至少有一个(0),一个(1)必然可以任意排序;否则直接判断一下即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/7 22:44:07
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n; cin >> n;
        vector <int> a(n), b(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        for (int i = 0; i < n; i++) {
            cin >> b[i];
        }
        sort(all(b));
        for (int i = 1; i < n; i++) {
            if (b[i] != b[i - 1]) {
                cout << "Yes" << '
    ';
                return;
            }
        }
        for (int i = 1; i < n; i++) {
            if (a[i] < a[i - 1]) {
                cout << "No" << '
    ';
                return;
            }
        }
        cout << "Yes" << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    C. Rotation Matching

    求位置差值出现次数最多个数即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/7 23:22:04
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n; cin >> n;
        vector <int> a(n), b(n);
        vector <vector <int>> v(n + 1); 
        for (int i = 0; i < n; i++) {
            cin >> a[i];
            v[a[i]].push_back(i);
            v[a[i]].push_back(i + n);
        }
        vector <int> cnt(n);
        for (int i = 0; i < n; i++) {
            cin >> b[i];
            for (auto it : v[b[i]]) {
                if (it >= i && it - i < n) {
                    ++cnt[it - i];
                }
            }
        }
        int ans = *max_element(all(cnt));
        cout << ans << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    D. Solve The Maze

    贪心堵住坏人,然后从终点出发bfs即可。
    细节见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/7 23:29:38
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n, m; cin >> n >> m;
        vector <string> mz(n);
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            cin >> mz[i];
            for (int j = 0; j < m; j++) {
                if (mz[i][j] == 'G') ++cnt;
            }
        }
        if (cnt == 0) {
            cout << "Yes" << '
    ';
            return;
        }
        const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
        auto ok = [&] (int x, int y) {
            return x >= 0 && x < n && y >= 0 && y < m;
        };
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mz[i][j] == 'B') {
                    for (int k = 0; k < 4; k++) {
                        int x = i + dx[k], y = j + dy[k];
                        if (ok(x, y)) {
                            if (mz[x][y] == '#') {}
                            if (mz[x][y] == '.') mz[x][y] = '#';
                            if (mz[x][y] == 'B') {}
                            if (mz[x][y] == 'G') {
                                cout << "No" << '
    ';
                                return;
                            }
                        }
                    }
                }
            }
        }
        if (mz[n - 1][m - 1] == '#') {
            cout << "No" << '
    ';
            return;
        }
        vector <vector <int>> d(n, vector <int>(m, -1));
        queue <pii> q;
        q.push(MP(n - 1, m - 1));
        d[n - 1][m - 1] = 0;
        while (!q.empty()) {
            pii now = q.front(); q.pop();
            int x = now.fi, y = now.se;
            for (int k = 0; k < 4; k++) {
                int nx = x + dx[k], ny = y + dy[k];
                if (ok(nx, ny) && mz[nx][ny] != '#') {
                    if (d[nx][ny] == -1) {
                        d[nx][ny] = d[x][y] + 1;
                        q.push(MP(nx, ny));   
                    }
                }   
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mz[i][j] == 'B' && d[i][j] != -1) {
                    cout << "No" << '
    ';
                    return;   
                }
                if (mz[i][j] == 'G' && d[i][j] == -1) {
                    cout << "No" << '
    ';
                    return;
                }
            }
        }
        cout << "Yes" << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    E. Maximum Subsequence Value

    注意到(k>3)的时候解一定没有前面优,大概的证明可以看看视频,如果有更优的那么之前的也能最优。
    所以只用考虑(kleq 3)的情况,所以(O(n^3))枚举就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/7 23:56:36
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n; cin >> n;
        vector <ll> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        if (n == 1) {
            cout << a[0] << '
    ';
            return;
        }
        ll ans = *max_element(all(a));
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                ans = max(ans, (a[i] | a[j]));
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int k = j + 1; k < n; k++) {
                    ans = max(ans, (a[i] | a[j]) | a[k]);
                }
            }
        }
        cout << ans << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    F. Swaps Again

    注意到对称位置上的数经过若干次操作过后位置也是对称的。
    所以直接(O(n^2))模拟就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/8 0:58:57
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n; cin >> n;
        vector <int> a(n), b(n), c(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        for (int i = 0; i < n; i++) {
            cin >> b[i];
        }
        vector <bool> vis(n);
        for (int i = 0; i < n / 2; i++) {
            int j = n - i - 1;
            for (int k = 0; k < n; k++) {
                if (!vis[k]) {
                    if (a[i] == b[k] && a[j] == b[n - k - 1]) {
                        c[k] = a[i];
                        c[n - k - 1] = a[j];
                        vis[k] = vis[n - k - 1] = true;
                        break;
                    }
                }
            }
        }
        if (n & 1) {
            c[n / 2] = a[n / 2];
        }
        for (int i = 0; i < n; i++) {
            if (c[i] != b[i]) {
                cout << "No" << '
    ';
                return;
            }
        }
        cout << "Yes" << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    G. Secure Password

    (val[i][0/1])表示当下标中第(i)个二进制位为(0/1),其余任意时,所有数或起来的值。
    那么对于每个下标可以每个二进制位单独计算,最后总的值或起来即是答案。
    但这种思路我们会询问(2logn)次,显然会超过(13),考虑只用(val[i][0])或者(val[i][1])来进行表示,这样询问次数满足条件,但是不能处理下标之间包含的关系,比如((i& j=i))这种。
    考虑将每个下标进行映射,映射过后任意两个下标都不存在包含与被包含的关系并且互不相等,此时可以只用(val[i][0])或者(val[i][1])得到答案。
    我们可以将每个数映射为包含(6)(1)的二进制数,({13choose 6}=1716>1000),所以这样肯定能够映射完所有的数的,之后直接对每个下标求解答案即可。
    询问次数至少为(logn)次。
    映射的这步十分巧妙!!其实前面的思路还比较好想,关键就是后面这里,神仙。。
    细节见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/8 19:27:10
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1000 + 5, P = 13;
     
    void run() {
        int n;
        cin >> n;
        vector <vector <int>> bit(P);
        vector <int> change(n);
        int k = 0;
        for (int i = 0; i < 1 << P; i++) {
            if (__builtin_popcount(i) != P / 2) continue;
            for (int j = 0; j < P; j++) {
                if (!(i >> j & 1)) {
                    bit[j].push_back(k + 1);
                }
            }   
            change[k++] = i;
            if (k == n) break;
        }
        auto query = [&] (vector <int>& q) {
            cout << '?' << ' ' << sz(q);
            for (auto it : q) {
                cout << ' ' << it;
            }
            cout << '
    ' << endl;
            ll t; cin >> t;
            return t;
        };
        vector <ll> val(P);
        for (int i = 0; i < P; i++) {
            if (sz(bit[i])) {
                val[i] = query(bit[i]);
            }
        }
        vector <ll> A(n);
        for (int i = 0; i < n; i++) {
            int x = change[i];
            for (int j = 0; j < P; j++) {
                if (x >> j & 1) {
                    A[i] |= val[j];
                }
            }
        }
        cout << "!";
        for (int i = 0; i < n; i++) {
            cout << ' ' << A[i];
        }
        cout << endl;
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    zoj 4120Tokens on the Segments(优先队列+贪心)
    hdu1710 Binary Tree Traversals(二叉树)
    poj3494Largest Submatrix of All 1’s
    poj 2559Largest Rectangle in a Histogram(单调栈简单模板题)
    poj 2492 A Bug's Life(种类并查集)
    差分约束 + spfa + 最长路 [NOI1999] 01串
    Codeforces Round #599 D Yet Another Monster Killing Problem
    CF 1249D1
    [Gym-102346A] 偷偷偷 并查集处理图(坐标)
    [Gym-102346M] 二分答案
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/13064328.html
Copyright © 2011-2022 走看看