zoukankan      html  css  js  c++  java
  • DISCO Presents Discovery Channel Code Contest 2020 Qual 题解

    A

    枚举一下

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        int x, y;
        cin >> x >> y;
        int ans = 0;
        if(x == 1) {
            ans += 300000;
        }
        if(x == 2) {
            ans += 200000;
        }
        if(x == 3) {
            ans += 100000;
        }
        if(y == 1) {
            ans += 300000;
        }
        if(y == 2) {
            ans += 200000;
        }
        if(y == 3) {
            ans += 100000;
        }
        if(x == 1 && y == 1) {
            ans += 400000;
        }
        cout << ans << '
    ';
        return 0;
    }
    View Code

    B

    枚举一下断点

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        vector<ll> a(n);
        ll sum = 0;
        for(int i = 0; i < n; ++i) {
            cin >> a[i];
            sum += a[i];
        }
        ll pre = 0, ans = sum;
        for(int i = 0; i < n; ++i) {
            pre += a[i];
            ans = min(ans, abs(2LL * pre - sum));
        }
        cout << ans << '
    ';
        return 0;
    }
    View Code

    C

    有草莓的行分段涂 没有的和有的合并

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        int n, m, k;
        cin >> n >> m >> k;
        int cnt = 0;
        vector<vector<int> > a(n, vector<int>(m, 0));
        for(int i = 0; i < n; ++i) {
            string s;
            cin >> s;
            for(int j = 0; j < m; ++j) {
                if(s[j] == '#') {
                    a[i][j] = ++cnt;
                    for(int k = j - 1; ~k; --k) {
                        if(a[i][k] || s[k] == '#') {
                            break;
                        }
                        a[i][k] = cnt;
                    }
                    for(int k = j + 1; k < m; ++k) {
                        if(a[i][k] || s[k] == '#') {
                            break;
                        }
                        a[i][k] = cnt;
                    }
                }
            }
        }
        cout << '
    ';
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j) {
                if(!a[i][j]) {
                    continue;
                }
                for(int k = i - 1; ~k; --k) {
                    if(a[k][j]) {
                        break;
                    }
                    a[k][j] = a[i][j];
                }
                for(int k = i + 1; k < n; ++k) {
                    if(a[k][j]) {
                        break;
                    }
                    a[k][j] = a[i][j];
                }
            }
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < m; ++j) {
                cout << a[i][j] << ' ';
            }
            cout << '
    ';
        }
        return 0;
    }
    View Code

    D

    思考一下发现 顺序与答案无关 (一个不严谨的证明:和是不变的 所以无关) 

    如果不进位的话 答案就是$sum_{i=1}^{n}{d_i}-1$

    考虑进位 那么每进一次位就是多出来一个1 

    设$sum=sum_{i=1}^{n}{d_i*c_i}$

    那么每次进位相当于$sum - 9$

    如果$sum<10$停止

    那么答案就是$sum_{i=1}^{n}{d_i}-1 + frac{sum_{i=1}^{n}{d_i*c_i} - 1}{9}$

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int maxn = 2e5 + 5;
    int n;
    ll d[maxn], c[maxn];
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cin >> n;
        for(int i = 1; i <= n; ++i) {
            cin >> d[i] >> c[i];
        }
        ll sum = 0, ans = 0;
        for(int i = 1; i <= n; ++i) {
            ans += c[i];
            sum += d[i] * c[i];
        }
        cout << ans - 1 + (sum - 1) / 9 << '
    ';
        return 0;
    }
    View Code

    E

    这个题不错

    如果能找出一个长度为$n$且红球蓝球数量差$<=1$的序列 并且知道其中一个红球和一个蓝球的位置 那么就能问出来所有了

    由于红球有n个 蓝球有n个 这样的序列肯定是存在的 

    设$ask(l, r)$表示询问$l-r$ 并且$r - l + 1 = n$

    假设$ask(1,n)=R$ 那么 $ask(n + 1, 2n) = B$

    并且存在某一个$i$使得$ask(i,i+n-1)$和$ask(i+1,i+n)$不同

    接着可以发现 这样的i是可以二分得出的

    那么先二分出这样的分界点 然后将其他所有点带进这个序列询问即可

    花费的询问次数是$2n-2 + log(n)+1 < 210$

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 205;
    int n, L, R;
    int ans[maxn];
    int Ask(int l, int r) {
        cout << '?';
        for(int i = l; i <= r; ++i) {
            cout << ' ' << i;
        }
        cout << '
    ';
        string ret;
        cin >> ret;
        return ret == "Red" ? -1 : 1; 
    }
    int Ask(int x) {
        cout << '?' << ' ' << x;
        for(int i = 1; i <= 2 * n; ++i) {
            if(i != L && i != R && (L < i && i < R) != (L < x && x < R)) {
                cout << ' ' << i;
            }
        }
        cout << '
    ';
        string ret;
        cin >> ret;
        return ret == "Red" ? -1 : 1;
    }
    int main() {
        cin >> n;
        int prv = Ask(1, n);
        int l = 1, r = n + 1;
        while(r - l > 1) {
            int mid = l + r >> 1;
            if(Ask(mid, mid + n - 1) == prv) {
                l = mid;
            } else {
                r = mid;
            }
        }
        ans[l] = prv;
        ans[l + n] = -prv;
        L = l;
        R = l + n;
        for(int i = 1; i <= 2 * n; ++i) {
            if(i != L && i != R) {
                ans[i] = Ask(i);
            }
        }
        cout << "! ";
        for(int i = 1; i <= 2 * n; ++i) {
            cout << (ans[i] == -1 ? 'R' : 'B');
        }
        cout << '
    ';
        return 0;
    }
    View Code

    F

    好难啊

    先将方阵分解成小方阵 小方阵中$d=1$ 也就是每次只走一步 不同方阵之间互相独立

    小方阵的长宽分别是$n/gcd(n,d)$和$m/gcd(m,d)$

    然后考虑方案 

    只有向下和不动方案是是$2^{m/gcd(m,d)}-1$

    只有向左和不动的方案是$2^{n/gcd(n,d)}-1$

    同时向下和向左的方案是$2^{gcd(n/gcd(n,d), m/gcd(m,d))}-1$

    最后一个比较抽象 这么考虑 把方阵按对角线分组 这样就有$gcd(n/gcd(n,d), m/gcd(m,d))$组

    每一组必须行动一致 向左或向下 这样为什么是对的 因为对于每个格子单独考虑 每一秒都只有一个人进一个人出 不会撞上

    如果对角线行动不一致 那么就会撞上

    最后乘上矩形数即可

    这种问题就是置换群的套路 分解成循环节 问题变得简单后再分类讨论

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int P = 1e9 + 7;
    ll h, w, t;
    ll power(ll x, ll t) {
        ll ret = 1;
        for(; t; t >>= 1, x = x * x % P) {
            if(t & 1) {
                ret = ret * x % P;
            }
        }
        return ret;
    }
    int main() {
        cin >> h >> w >> t;
        ll n = h / __gcd(h, t), m = w / __gcd(w, t);
        ll tmp = (power(2LL, n) + power(2LL, m) + power(2LL, __gcd(n, m)) - 3 + P) % P;
        ll c = __gcd(h, t) * __gcd(w, t);
        cout << power(tmp, c) << '
    ';
        return 0;
    }
    View Code
  • 相关阅读:
    微信小程序支付服务商版-发起支付
    count(1),count(*),count(主键) 性能对比
    SpringBoot_yml配置文件
    Java字符串加密,UUID+MD5进行加密
    WebSocket实现C#端和H5进行交互
    SpringBoot配置文件详解
    SQL中的limit
    SQL中的union简述
    数据库中的子查询
    数据库中的连接查询
  • 原文地址:https://www.cnblogs.com/19992147orz/p/12258491.html
Copyright © 2011-2022 走看看