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;
}
原文地址:https://www.cnblogs.com/heyuhhh/p/10886903.html