具体思路就是贪心去凑, 对于iin, 需要出一个i, 要一个w, 即(i, w), 若有要一个i, 出一个w就能形成互补, 即(i, w) (w, i) 互补, 如果没有互补这种情况, 则要中转一次, 即 (i, w) (w, n) (n, i) 这种, 而对于iii, 就是需要转两次, (i, w)一次, (i, n)一次, 转完一次后都和第一种情况符合, 据题意牌面固定, 只可能出现这两种情况, 模拟即可。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define debug cout<<"debug"<<endl
typedef long long ll;
typedef long double ld;
typedef pair<int, int> PII;
const double eps = 1e-8;
const double PI = 3.14159265358979323;
const int N = 2e5+10, M = 2*N, mod = 1e9+7;
const int INF = 0x3f3f3f3f;
int n;
string win = "win";
void solve()
{
cin>>n;
vector<vector<set<int>>> v(3, vector<set<int>> (3));
for(int i = 1; i<=n; i++)
{
string s; cin>>s;
for(int j = 0; j<3; j++)
{
for(int k = 0; k<3; k++)
{
if(j == k) continue;
// inn 出一种, 出n要w // iii 出两种, 可以先出一种转成前者, 出i要n, 出i要w, 要中转
int s1 = count(s.begin(), s.end(), win[j]);
int s2 = count(s.begin(), s.end(), win[k]);
if(s1>=2 && s2==0) v[j][k].insert(i); // 出win[j]要win[k]
}
}
}
vector<vector<int>> res;
for(int i = 1; i<=n; i++)
{
for(int j = 0; j<3; j++)
{
for(int k = 0; k<3; k++)
{
// 出j要k 与 出k要j互补
if(v[j][k].count(i)) // 有互补情况, 直接凑成
{
if(v[k][j].size()>0)
{
auto it = v[k][j].begin();
res.push_back({i, j, *it, k});
v[j][k].erase(i), v[k][j].erase(it);
}else{ // 无互补情况 要转两次, 先转一次
for(int t = 0; t<3; t++)
{
if(v[k][t].size()>0)
{
auto it = v[k][t].begin();
res.push_back({i, j, *it, k}), v[j][t].insert(*it); // 转一次
v[j][k].erase(i), v[k][t].erase(it);
break; // 只转一次
}
}
}
}
}
}
}
cout<<res.size()<<endl;
for(auto t : res) cout<<t[0]<<" "<<win[t[1]]<<" "<<t[2]<<" "<<win[t[3]]<<endl;
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T;
T = 1;
cin>>T;
while(T -- )
{
solve();
}
return 0;
}