解题思路:逆向思维
枚举每个操作,然后判断该操作是不是最后一个操作。(就像撕胶布一样,一条一条的剥离)
判断是否是最后一个操作的方法是:
除去已经用过的点( 即标记成0的点,可以充当任何颜色 ),如果操作的那一排都等于当前操作的颜色,那就是最后一个操作。然后再把操作过的点给标记,重复m次。
枚举每个操作,然后判断该操作是不是最后一个操作。(就像撕胶布一样,一条一条的剥离)
判断是否是最后一个操作的方法是:
除去已经用过的点( 即标记成0的点,可以充当任何颜色 ),如果操作的那一排都等于当前操作的颜色,那就是最后一个操作。然后再把操作过的点给标记,重复m次。
最后逆向输出记录下的操作的编号即可。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <vector>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define eps 1e-8;
const int INF=0x3f3f3f3f;
const int maxn=100+10;
const int maxm=500+10;
int rec1[maxn][maxn],rec2[maxn][maxn],x[maxm],y[maxm];
char op[maxm][2];
int op_rank[maxm];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&rec1[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&rec2[i][j]);
for(int i=1;i<=m;i++)
{
scanf("%s%d%d",op[i],&x[i],&y[i]);
}
int rank=0;
while(rank<m)
{
for(int i=1;i<=m;i++)
if(x[i])
if(op[i][0]=='L')
{
int j;
for(j=1;j<=n;j++)
if(rec2[j][x[i]]&&rec2[j][x[i]]!=y[i])break;
if(j>n)
{
op_rank[rank++]=i;
for(j=1;j<=n;j++)rec2[j][x[i]]=0;
x[i]=0;
}
}
else
{
int j;
for(j=1;j<=n;j++)
if(rec2[x[i]][j]&&rec2[x[i]][j]!=y[i])break;
if(j>n)
{
op_rank[rank++]=i;
for(j=1;j<=n;j++)rec2[x[i]][j]=0;
x[i]=0;
}
}
}
for(int i=rank-1;i>=0;i--)
{
printf("%d",op_rank[i]);
if(i==0)printf("\n");
else printf(" ");
}
}
return 0;
}