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

    Codeforces Round #561 (Div. 2) 题解

    题目链接

    A. Silent Classroom

    水题。

    Code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 105;
    int n;
    char s[N], t[N];
    int main() {
        cin >> n;
        for(int i = 1; i <= n; i++) {
            scanf("%s", t + 1);
            s[i] = t[1] ;
        }
        sort(s + 1, s + n + 1) ;
        int cnt = 0;
        int ans = 0;
        for(int i = 1; i <= n + 1; i++) {
            if(s[i] != s[i - 1]) {
                if(cnt == 0) cnt = 1;
                else {
                    int tmp = cnt / 2;
                    ans += tmp * (tmp - 1) / 2 + (cnt - tmp) * (cnt - tmp - 1) / 2;
                    cnt = 1;
                }
            } else cnt++;
        }
        cout << ans ;
        return 0;
    }
    

    B. All the Vowels Please

    满足行列都大于5就行了,后面乱构造一下就好了。
    代码如下:

    Code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 105;
    int n;
    char s[N] = {'0', 'a', 'e', 'i', 'o', 'u'} ;
    int main() {
        cin >> n;
        int r, c = -1;
        for(int i = 5; i < n; i++) {
            if(n % i == 0 && n / i >= 5) {
                r = i;
                c = n / i;
                break ;
            }
        }
        if(c == -1) {
            cout << -1;
            return 0;
        }
        for(int i = 1; i <= r; i++) {
            int k = (i - 1) % 5 + 1;
            for(int j = 1; j <= c; j++) {
                cout << s[(j + k - 2) % 5 + 1] ;
            }
        }
        return 0;
    }
    

    C. A Tale of Two Lands

    比赛时硬生生分情况讨论...最后可能是因为细节原因还是没有A出来。好吧傻逼了。
    对于(|x|,|y|)来说,(x,y)的正负并不会产生什么影响;对于(|x-y|,|x+y|)来说,(x,y)的正负也不会产生什么影响。所以我们就可以直接对(a_i)取绝对值,只看为正数的情况就好了。
    然后就随便推一下,把绝对值去掉就行了。
    代码如下:

    Code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5 + 5;
    int n;
    ll a[N], b[N];
    int main() {
        ios::sync_with_stdio(false); cin.tie(0) ;
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i] < 0 ? -a[i] : a[i] ;
        sort(b + 1, b + n + 1) ;
        ll ans = 0;
        int l = 1, r = 2;
        while(r <= n) {
            while(l < r && b[l] * 2 < b[r]) l++;
            ans += r - l;
            r++;
        }
        cout << ans;
        return 0;
    }
    

    D. Cute Sequences

    这个题上午把我整自闭了...还是细节方面没有处理好。
    首先可以推出(x_n=2^{n-2}*a+2^{n-3}*r_2+cdots+2*r_{n-2}+r_{n-1}+r_n),因为(1leq rleq m),我们可以知道如果存在一个(n)满足条件,那么有(2^{n-2}*(a+1)leq bleq 2^{n-2}*(a+m)),通过这个来判断是否存在合理情况就行了。我一开始判断这里的时候爆long long了。。。也搞了我半天。
    之后我们就开始构造方案,首项为(a),我们先令(r_i=1),那么此时最大项的值就为(2^{n-2}*(a+1)),现在要做的就是改变某些(r_i)的值,使得最后最大项等于(b)
    (R=b-2^{n-2}*(a+1)),根据我们之前推出来的式子,可以知道(r_i)之前的系数为(2^{n-i-1}),贪心来构造的话就是每次找到一个最大的(X),满足(X*2^{n-i-1}leq R 且 (X+1)*2^{n-i+1}>R),并且(1leq Xleq m),然后每次令(r_i)等于(X)即可。
    这样来构造的话最后是肯定保证有解的。
    代码如下:

    Code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 105;
    const ll MAX = 1e14 ;
    ll q, a, b, m;
    ll r[N] ;
    ll qp(ll A, ll B) {
        ll ans = 1;
        while(B) {
            if(B & 1) ans = ans * A;
            A = A * A;
            B >>= 1;
        }
        return ans ;
    }
    int main() {
        ios::sync_with_stdio(false); cin.tie(0) ;
        cin >> q;
        while(q--) {
            memset(r, 0, sizeof(r)) ;
            cin >> a >> b >> m;
            if(a == b) {
                cout << 1 << ' ' << a << '
    ' ;
                continue ;
            }
            int p = -1;
            for(int i = 2; i <= 50; i++) {
                if(qp(2, i - 2) * (a + 1) > MAX) break ;
                if(qp(2, i - 2) * (a + 1) <= b && qp(2, i - 2) * (a + m) >= b) {
                    p = i;
                    break ;
                }
            }
            if(p == -1) {
                cout << -1 << '
    ';
                continue ;
            }
            ll R = b - qp(2, p - 2) * (a + 1);
            ll S = a;
            for(int i = 2; i < p; i++) {
                ll now = qp(2, p - i - 1) ;
                ll x = min(R / now, m - 1) ;
                r[i] = x;
            }
            S = a;
            cout << p << ' ' << S << ' ';
            for(int i = 2; i < p; i++) {
                cout << S + r[i] + 1 << ' ' ;
                S += S + r[i] + 1;
            }
            cout << b << '
    ' ;
        }
        return 0;
    }
    

    E. The LCMs Must be Large

    这是个很有意思的题。首先很容易证明如果存在两天,在这两天中得到的数字集合不存在交集,那么肯定是无解的。
    主要就是证明两两天数之间存在交集时,为什么一定方案有解。
    可以这样来构造,如果在第(j)天去了({a_1,a_2,cdots,a_k})这些商店,那么我们将这些位置的数都乘以第(j)个质数。
    最后如果两两天数之间存在交集的话,那么它们的lcm肯定为所有质数的乘积,而它们补集的lcm肯定不存在当前天的质数。
    所以这种构造方案就可以保证任意两天存在交集时是一定有解的。
    由于(m)的范围很小,所以求是否有交时暴力一下就行了。
    代码如下:

    Code
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int M = 55, N = 1e4 + 5;
    int m, n;
    int s[N] ;
    vector <int> v1[N], v2[M] ;
    bool vis[M] ;
    int main() {
        ios::sync_with_stdio(false); cin.tie(0);
        cin >> m >> n;
        for(int i = 1; i <= m; i++) {
            int x, y;
            cin >> x;
            for(int j = 1; j <= x; j++) {
                cin >> y;
                v1[y].push_back(i) ;
                v2[i].push_back(y) ;
            }
        }
        int ok = 1;
        for(int i = 1; i <= m; i++) {
            memset(vis, 0, sizeof(vis)) ;
            int cnt = 0;
            for(auto other : v2[i]) {
                for(auto v : v1[other]) {
                    if(!vis[v]) vis[v] = 1, cnt++;
                }
            }
            if(cnt < m) {
                ok = 0;
                break ;
            }
        }
        if(ok) cout << "possible" ;
        else cout << "impossible";
        return 0;
    }
    
  • 相关阅读:
    快速幂,矩阵乘法,矩阵快速幂
    关于xor
    数位dp
    tarjan,割边,桥,割点
    RMQ,ST表,dp
    逆序对,树状数组,归并排序
    线段树
    dp,LCS
    清北 游
    青蛙的约会(扩展欧几里得)
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10886903.html
Copyright © 2011-2022 走看看