题目
题意: 给定m个w、i、n,随机分配给m个人,每人3个字母。现在可以让任意两个人交换手中的一个字母,求最少需要交换多少次并输出方案.
思路: 如果某个人多w且没有i,就标记为w->i;如果某个人多i且没有w,就标记i->w,二者可以交换满足对方的条件。依次类推。
但是还要注意另一种情况,如果存在 w->i, i->n, n->w; w->n, n->i, i->w. 不能相互抵消,但是可以通过两次交换满足这三个要求。1和2先换,2和3的需求就变成互补的了,2和3再换.
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n,m,k,T;
int get(int a,int b) //哪种交换
{
if(a==1&&b==2) return 1;
if(a==2&&b==1) return 2;
if(a==1&&b==3) return 3;
if(a==3&&b==1) return 4;
if(a==2&&b==3) return 5;
if(a==3&&b==2) return 6;
}
void output(int x)
{
if(x==1) cout<<'w';
if(x==2) cout<<'i';
if(x==3) cout<<'n';
cout<<' ';
}
int cnt[N][4];
vector<int> va[7];
struct node{
int l;
int t1;
int r;
int t2;
void print()
{
cout<<l<<" ";
output(t1);
cout<<r<<" ";
output(t2);
cout<<"\n";
}
};
void solve()
{
vector<node> res;
m = 3;
cin>>n;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j) cnt[i][j] = 0;
char ch;
for(int j=0;j<m;++j)
{
cin>>ch;
if(ch=='w') cnt[i][1]++;
if(ch=='i') cnt[i][2]++;
if(ch=='n') cnt[i][3]++;
}
int idx1 = 0; //哪个字母多
int idx2 = 0,idx3 = 0; //哪些字母少
for(int j=1;j<=m;++j)
{
if(cnt[i][j]>1) idx1 = j;
if(cnt[i][j]==0)
{
if(!idx2) idx2 = j;
else idx3 = j;
}
}
if(idx1&&idx2) va[get(idx1,idx2)].push_back(i);
if(idx1&&idx3) va[get(idx1,idx3)].push_back(i);
}
for(int i=1;i<=5;i+=2)
{
while(va[i].size()&&va[i+1].size())
{
int idx1 = va[i].back();
int idx2 = va[i+1].back();
va[i].pop_back(); va[i+1].pop_back();
if(i==1)
res.push_back({idx1,1,idx2,2});
if(i==3)
res.push_back({idx1,1,idx2,3});
if(i==5)
res.push_back({idx1,2,idx2,3});
}
}
int l = 1,mid = 5,r = 4;
while(va[l].size()&&va[mid].size()&&va[r].size())
{
int idx1 = va[l].back();
int idx2 = va[mid].back();
int idx3 = va[r].back();
va[l].pop_back(); va[mid].pop_back(); va[r].pop_back();
res.push_back({idx1,1,idx2,2});
res.push_back({idx2,1,idx3,3});
}
l = 3,mid = 6,r = 2;
while(va[l].size()&&va[mid].size()&&va[r].size())
{
int idx1 = va[l].back();
int idx2 = va[mid].back();
int idx3 = va[r].back();
va[l].pop_back(); va[mid].pop_back(); va[r].pop_back();
res.push_back({idx1,1,idx2,3});
res.push_back({idx2,1,idx3,2});
}
cout<<res.size()<<"\n";
for(auto &item:res)
{
item.print();
}
}
signed main(void)
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>T;
while(T--) solve();
return 0;
}