Codeforces Round #850 (Div. 1, based on VK Cup 2022 - Final Round) B.Letter Exchange

topic

m (m<=1e5) individuals, each person has a string of length 3 consisting of only w, i, n,

And m people have exactly m w, m i, m n,

Now we need to exchange, each time you can choose two people a and b, and exchange a certain letter of a with a certain letter of b

After several exchanges, the string in everyone's hand happens to be win

Output the minimum number of exchanges, and the corresponding exchange sequence

Actual t (t<=1e4) sets of data, to ensure that the sum of m does not exceed 1e5

source of ideas

cuiaoxiang code

answer

It took 1 hour to do 150 lines in the game, but the actual 60-70 lines took about 20 minutes

First of all, if the win letter is marked as 012, there are only 10 cases, of which 012 does not need to be changed

000,111,222

001,110

002,220

112,221

012

However, 0 is more and 1 is less, corresponding to the two cases of 000 and 002, and recorded in vector<int>a[0][1], which means that 0 needs to be given to 1

Other corresponding situations, and so on

Among them, 000 appears not only in the situation of more than 1 and less, but also in the situation of more than 2 and less

 

1. Two-membered ring, a[0][1]<->a[1][0], a[0][2]<->a[2][0], a[1][2]< ->a[2][1], priority operation

2. After it cannot be operated, only the three-membered ring remains, a[0][1]->a[1][2]->a[2][0], a[1][0]->a[ 0][2]->a[2][1], just operate

the code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<array>
using namespace std;
const string S="win";
int T,n;
vector<int>a[3][3];
int g(char c){return S.find(c);}
bool has(vector<int>&x){return !x.empty();}
int get(vector<int>&x){int y=x.back();x.pop_back();return y;}
string s;
int main(){
    cin>>T;
    while(T--){
        cin>>n;
        for(int i=0;i<3;++i){
            for(int j=0;j<3;++j){
                a[i][j].clear();
            }
        }
        for(int i=1;i<=n;++i){
            cin>>s;
            vector<int>cnt(3);
            for(int j=0;j<3;++j){
                cnt[g(s[j])]++;
            }
            for(int x=0;x<3;++x){
                for(int y=0;y<3;++y){
                    if(x==y)continue;
                    if(cnt[x]>1 && cnt[y]<1){
                        a[x][y].push_back(i);
                        cnt[x]--;
                        cnt[y]++;
                    }
                }
            }
        }
        vector<array<int,4>>ans;
        for(int x=0;x<3;++x){
            for(int y=x+1;y<3;++y){
                vector<int>&fi=a[x][y];
                vector<int>&se=a[y][x];
                while(has(fi) && has(se)){
                    int f=get(fi),s=get(se);
                    ans.push_back({f,x,s,y});
                }
            }
        }
        {
            vector<int>&fi=a[1][0];
            vector<int>&se=a[0][2];
            vector<int>&th=a[2][1];
            while(has(fi) && has(se) && has(th)){
                int f=get(fi),s=get(se),t=get(th);
                ans.push_back({f,1,s,0});
                ans.push_back({s,1,t,2});
            }
        }
        {
            vector<int>&fi=a[0][1];
            vector<int>&se=a[1][2];
            vector<int>&th=a[2][0];
            while(has(fi) && has(se) && has(th)){
                int f=get(fi),s=get(se),t=get(th);
                ans.push_back({f,0,s,1});
                ans.push_back({s,0,t,2});
            }
        }
        cout<<(int)ans.size()<<endl;
        for(auto [i,x,j,y]:ans){
            cout<<i<<" "<<S[x]<<" "<<j<<" "<<S[y]<<'\n';
        }
    }
    return 0;
}

 

 

Guess you like

Origin blog.csdn.net/Code92007/article/details/128895633