ABC 略
D
纯模拟。观察发现我们从第一列任意一个位置出发,找到同一行后面大于这个数的数,跳到这个位置,然后可以上下移动,然后继续上一步操作,问是否可以到达最后一列。外层从小到大枚举每种类型的牌,内层枚举三个人,维护出每个人当前类型之前的最大的数的值和位置与由哪一列跳到这一列,如果当前位置小于维护的这个值,就可以到达,如果这个类型存在一个位置可以到达,那么更新三个人当前类型之前的最大值和位置。答案输出类似与dp中递归输出方案
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int T,n,a[4][N],tot;
pair<int,int> maxx[4];
pair<int,pair<int,int> >f[N],ans[N];
void init()
{
tot=0;
}
void solve()
{
cin>>n;
init();
for(int i=1;i<=3;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
for(int i=1;i<=3;i++)
maxx[i]={a[i][1],1};
bool flag;
for(int i=2;i<=n;i++)
{
flag=false;
for(int j=1;j<=3;j++)
{
if(a[j][i]<maxx[j].first)
{
f[i]={maxx[j].second,{j,i}};
flag=true;
break;
}
}
if(!flag) continue;
for(int j=1;j<=3;j++)
{
if(a[j][i]>maxx[j].first)
{
maxx[j]={a[j][i],i};
}
}
}
string s=" qkj";
if(flag)
{
cout<<"YES"<<endl;
int p=n;
while(p>1)
{
ans[++tot]=f[p];
p=f[p].first;
}
cout<<tot<<endl;
for(int i=tot;i>=1;i--)
cout<<s[ans[i].second.first]<<" "<<ans[i].second.second<<endl;
}
else cout<<"NO"<<endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>T;
while(T--) solve();
}