题意:由这个状态转换成这个状态。给你m个操作,问你m个操作的顺序。必定可以完成。
那么就可以逆向推导。因为一定可以变成这样。
#include<stdio.h>
#include<string.h>
int num[102][101],num2[102][102];
char str[505][2];
int m1[505],m2[505];
int a[101],b[101];
int n,m;
void debug()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
printf("%d%c",num2[i][j],j==n?'\n':' ');
}
int panduan(int i)
{
if(str[i][0]=='H')
{
//printf("H i== %d \n",i);
for(int j=1; j<=n; j++)
{
if(num2[m1[i]][j]==0)continue;
if(m2[i]!=num2[m1[i]][j])
return 0;
}
for(int j=1; j<=n; j++)
num2[m1[i]][j]=0;
return 1;
}
else
{
// printf("L i==%d\n",i);
for(int j=1; j<=n; j++)
{
if(num2[j][m1[i]]==0)continue;
if(m2[i]!=num2[j][m1[i]])
{
// debug();
// printf("i===%d\n",i+1);
return 0;
}
}
for(int j=1; j<=n; j++)
num2[j][m1[i]]=0;
return 1;
}
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&num[i][j]);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&num2[i][j]);
for(int i=0; i<m; i++)
{
getchar();
scanf("%s",&str[i]);
getchar();
scanf("%d%d",&m1[i],&m2[i]);
}
int cnt=0,k[505];
int vis[505];
memset(vis,0,sizeof(vis));
int kk=0;
while(1)
{
for(int i=0; i<m; i++)
{
if(!vis[i])
{
if(panduan(i))
{
//printf("YES %d\n",i+1);
vis[i]=1;
k[cnt++]=i+1;
kk++;
}
}
}
if(kk==m)break;
}
for(int i=0; i<m; i++)
if(!vis[i])
k[cnt++]=i+1;
for(int i=cnt-1; i>=0; i--)
printf("%d%c",k[i],i==0?'\n':' ');
}
return 0;
}