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;
}