P7940题解
tongyanmin · · 题解
Solution
由题意,我们必须恰好改变每队恰好
下面讲讲我的做法。
我们不妨定义修改 A 组的操作为操作
- 依次使用操作
x,y ,构造出 A 组全胜的状态。 - 在经过上一步之后,可能存在操作次数还未用完的情况。对此我们不妨找出之前未被修改的对局(即 A 组本来就胜利的情况),同时对
a_i,b_i 进行修改,使得两种操作的使用次数同时增加。 - 经过以上两轮之后,可以发现要么已经构造完毕,要么还剩下一次
y 操作(第1 步中可能会出现cnt_x=cnt_y+1 的情况)。对于这种情况,不妨找出第一次被修改的对局,对其使用一次y 操作即可。
Code
#include<bits/stdc++.h>
using namespace std;
int t,n,a[200005],b[200005],c[200005],d[200005];//把修改后的数存在数组c,d中
bool check(int x,int y){
if(x==1&&y==2)return 1;
if(x==2&&y==3)return 1;
if(x==3&&y==1)return 1;
return 0;
}//判断胜负
bool vis[200005];
int main(){
cin>>t;
while(t--){
cin>>n;
int cnt=0,cntx=0,cnty=0;
for(int i=1;i<=n*2;i++){
cin>>a[i];
c[i]=a[i];
vis[i]=0;
}
for(int i=1;i<=n*2;i++){
cin>>b[i];
d[i]=b[i];
}
for(int i=1;i<=2*n;i++){
if(check(a[i],b[i]))continue;
cnt++;
if(cnt%2==1){
cntx++;
c[i]=d[i]-1;
if(c[i]==0)c[i]=3;
}//改a
else{
cnty++;
d[i]=c[i]+1;
if(d[i]==4)d[i]=1;
}//改b
vis[i]=1;
}//改为a必胜的局面
for(int i=1;i<=2*n;i++){
if(vis[i])continue;
if(cntx<n&&cnty<n){
c[i]+=1;
if(c[i]==4)c[i]=1;
d[i]+=1;
if(d[i]==4)d[i]=1;
cntx++,cnty++;
}
if(cntx==cnty&&cntx==n)break;
}//消耗多余的操作次数
if(cnty<n){
for(int i=1;i<=n*2;i++){
if(vis[i]){
for(int j=1;j<=3;j++){
for(int k=1;k<=3;k++)
if(j!=a[i]&&k!=b[i]&&check(j,k))c[i]=j,d[i]=k;
}//此处直接暴力修改即可,记得判重
break;
}
}
}
cout<<n*2<<endl;
for(int i=1;i<=n*2;i++)cout<<c[i]<<" ";
cout<<endl;
for(int i=1;i<=n*2;i++)cout<<d[i]<<" ";
cout<<endl;
}
return 0;
}