Codeforces Round #630 (Div. 2)【ABCDE】(题解)

目录

涵盖知识点:思维、构造。

比赛链接:传送门

A - Exercising Walk

题意: 给定一块区域的坐标范围和初始点,要求分别\(a,b,c,d\)次向上下左右移动,问能否达到要求。
题解: 依次抵消判边界,特判夹死的状况。
Accept Code:

#include <bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        int x,y,x1,y1,x2,y2;
        cin>>x>>y>>x1>>y1>>x2>>y2;
        if(a-b>x-x1||b-a>x2-x||c-d>y-y1||d-c>y2-y||((a+b)&&(x1==x2))||((c+d)&&(y1==y2)))
            puts("No");
        else puts("Yes");
    }
    return 0;
}

B - Composite Coloring

题意: 用不超过11种颜色给合数数组染色,保证同色的数不互质。
题解: 数组范围1000以内,而100以内的质数共11个。素因子分解按照最小素因子分配颜色。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
int res[1010];
map<int,int> mp;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int cnt=0;
        mp.clear();
        for(int i=0,a;i<n;i++){
            cin>>a;
            for(int j=2;j<=sqrt(a);j++){
                if(a%j==0){
                    if(mp[j])res[i]=mp[j];
                    else res[i]=mp[j]=++cnt;
                    break;
                }
            }
        }
        cout<<cnt<<"\n";
        for(int i=0;i<n;i++)
            cout<<res[i]<<" ";
        cout<<"\n";
    }
    return 0;
}

C - K-Complete Word

题意: 问改变几个字母使字符串为回文且周期为\(k\)
题解: 只有\(n\div k\)个长度为\(k\)的回文串拼接才满足效果。所以我们一一配对,对于每个位置选择一个满足条件最多的数加入对最后答案的贡献。具体实现见代码。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int cnt[maxn][26];
int calc(int u,int v){
    int res=0,mx=0;
    for(int i=0;i<26;i++){
        res+=cnt[u][i]+cnt[v][i];
        mx=max(mx,cnt[u][i]+cnt[v][i]);
    }
    return res-mx;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        //memset(cnt,0,sizeof cnt);
        int n,k;
        string s;
        cin>>n>>k>>s;
        for(int i=0;i<k;i++){
            for(int j=0;j<26;j++)cnt[i][j]=0;
        }
        for(int i=0;i<s.length();i++)cnt[i%k][s[i]-'a']++;
        int ans=0;
        for(int i=0;i<k;i++)ans+=calc(i,k-i-1);
        cout<<ans/2<<"\n";
    }
    return 0;
}

D - Walk on Matrix

题意: 构造一个矩阵,要求根据题目所给算法算出的最后答案和真实最大值相差为\(k\)
题解:

\[\left( \begin{array}{ccc} 2^{17}+k & 2^{17} & 0\\ k & 2^{17}+k & k\\ \end{array} \right) \]

Accept Code:

#include <bits/stdc++.h>
using namespace std;
int main(){
    int k;
    cin>>k;
    cout<<"2 3\n";
    int x=(1<<17);
    cout<<(x^k)<<" "<<x<<" 0\n";
    cout<<k<<" "<<(x^k)<<" "<<k<<"\n";
    return 0;
}

E - Height All the Same

题意: 一个\(N×M\)的网格图上的每个网格初始放有高度在\([L,R]\)范围内的立方体木块。你每次能在这个网格图中选择一个位置加上2个立方体木块,或者选择两个相邻位置各加上1个木块,询问有几种初始状态能够经过有限次操作是的所有位置的木块高度一致。
题解: 因为不论怎么操作,都是给现有的方块堆加上2个方块,因此奇偶性不变。我们假设初始最高的一堆木块高度为 \(h\),如果最终能够使得所有位置高度一致为\(k\),则需要满足:\((n*m*k+(n*m*h−\sum cnt_{i,j})) \%2 = 0\),其中 \(cnt_{i,j}\) 指代网格图中位置为\((i,j)\)的方块数。
不难发现如果\(n*m\)为奇数,则上式必然能成立,则方案数为\((R−L+1)^{nm}\);若\(n*m\)为偶数,则能否变成高度一致取决于\(n*m*h−\sum pos_{i,j}\)的奇偶性,又因为此时\(n*m\)为偶数,因此初始的总方块数若为奇数就必定不行,我们减去初始方块数为奇数的情况即为答案。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll qpow(ll a, ll b, ll p){
    ll ans = 1;
    while (b){
        if (b & 1)
            ans = ans * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ans;
}
int main(){
    ll n, m, l, r;
    cin>>n>>m>>l>>r;
    if ((n & 1) && (m & 1))
        printf("%lld\n", qpow((r - l + 1), n * m, mod));
    else{
        ll even = r / 2ll - (l - 1ll) / 2ll, odd = r - l + 1ll - even;
        ll ans = (qpow(r - l + 1, m * n, mod) - qpow(odd - even, m * n, mod) + mod) % mod;
        ans = (ans * qpow(2ll, mod - 2ll, mod)) % mod;
        ans = (qpow(r - l + 1, n * m, mod) - ans + mod) % mod;
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/charles1999/p/12612071.html