Codeforces Round 897 (Div. 2)

目录

    • A. green_gold_dog, array and permutation
    • B. XOR Palindromes
    • C. Salyg1n and the MEX Game
    • D. Cyclic Operations

A. green_gold_dog, array and permutation

思路:贪心,我们尽可能让大的数和小的数进行匹配即可。

#include 

using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;

void solve()
{
    int n;
    cin>>n;
    vector<pll> a(n+5);
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        a[i]={x,i};
    }
    vector<int> b(n+5);
    sort(a.begin()+1,a.begin()+1+n);
    for(int i=n;i>=1;i--){
        int c=n-i+1;
        b[a[c].second]=i;
    }
    for(int i=1;i<=n;i++) cout<<b[i]<<" ";
    cout<<endl;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    system("pause");
    return 0;
}

B. XOR Palindromes

思路:我们发现回文字符串对应位置不匹配时的贡献为1,否则贡献为2,我们统计对应两种情况的贡献数目即可,然后根据字符串的长度进行分类讨论,因为当字符串长度为奇数时,中心字符也有1的贡献。

#include 

using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;


void solve()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    int cnt1=0;
    int cnt2=0;
    for(int i=0;i<(n+1)/2;i++){
        if(s[i]==s[n-i-1]){
            cnt1++;
        }
        else{
            cnt2++;
        }
    }
    vector<int> a(n+5);
   	if(n%2){//当为奇数时,中心字符串的贡献不计入为2的贡献中
        for(int i=cnt2,j=0;j<cnt1;j++,i+=2){//只用对1进行修改
            a[i]=1;
            a[i+1]=1;
        }
    }
    else{
        for(int i=cnt2,j=0;j<=cnt1;j++,i+=2){
            a[i]=1;
           // a[i+1]=1;
        } 
    }
    for(int i=0;i<=n;i++) cout<<a[i];
    cout<<endl;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    system("pause");
    return 0;
}

C. Salyg1n and the MEX Game

思路:思维,我们操作Alice,除开第一次以外,我们可以贪心想到,bob拿走了什么数,我们就把他对应的数放进去即可,那么现在考虑第一次操作,因为我们想让结果最优,所以直接放入原序列的 m e x mex mex值即可。

#include 

using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;


void solve()
{
    int n;
    cin>>n;
    set<int> se;
    for(int i=0;i<n;i++) {
        int x;
        cin>>x;
        se.insert(x);
    }
    int res=0;
    int c=0;
    for(auto x: se){
        if(x!=c) break;
        c++;
    }
    cout<<c<<endl;
    cout.flush();
    while(1){
        int x;
        cin>>x;
        if(x==-1) return;
        cout<<x<<endl;
        cout.flush();
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    system("pause");
    return 0;
}

D. Cyclic Operations

思路:我们构造b数组时,以a数组为 [ 2 , 3 , 4 , 2 ] [2,3,4,2] [2,3,4,2], k = 3 k=3 k=3,为例:
我们可以首先构造除 l = [ 1 , 2 , 3 ] l=[1,2,3] l=[1,2,3],那么此时的a数组为 [ 2 , 3 , 1 , 0 ] [2,3,1,0] [2,3,1,0],
我们可以接着构造 l = [ 2 , 3 , 4 ] l=[2,3,4] l=[2,3,4]那么此时的a数组为 [ 2 , 3 , 4 , 2 [2,3,4,2 [2,3,4,2
Codeforces Round 897 (Div. 2)_第1张图片
我们根据上面的构造,我们会发现,若把下标和对应的点进行连边,我们会得到这样一个图,且对于每一个下标,我们需要在该位置放的值也刚好构成这样的关系。此时我们就考虑构造出来的图中,每个环上的节点是否为k即可。
因为如果环的节点个数不为k,那么我们无论如何也无法构造出合法的环。(因为根本不存在相应大小为k的环)。
具体考察的算法就是基环树,因为每个下标都跟值连单向边,所有只会有n条边存在。但整个不一定连同,所以其本质上是基环树森林。

#include

using namespace std;
const int N=4e7+5;
typedef long long ll;
typedef pair<ll,ll > pll;
typedef array<int,3> p3;
int mod=998244353;
const int maxv=4e6+5;


void solve()
{	
    int n,k;
    cin>>n>>k;
    vector<int >a(n+5);
    for(int i=1;i<=n;i++) cin>>a[i];
    if(k==1){//注意k等于1时要进行特判
        for(int i=1;i<=n;i++){
            if(a[i]!=i){
                cout<<"NO"<<endl;
                return ;
            }
        }
        cout<<"YES"<<endl;
    }
    else{
        vector<int> st(n+5,-1);
        for(int i=1;i<=n;i++){
            int j=i;
            while(st[j]==-1){
                st[j]=i;
                j=a[j];
            }
            if(st[j]==i){
                int cnt=0;
                int x=j;
                do{
                    cnt++;
                    x=a[x];
                }while(x!=j);
                if(cnt!=k){
                    cout<<"NO"<<endl;
                    return ;
                }
            }
        }
        cout<<"YES"<<endl;
    }
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
    int t;
	t=1;
	cin>>t;
    while(t--){
        solve();
    }
	system("pause");
	return 0;
}

你可能感兴趣的:(cf补题,算法,c++,数据结构)