题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5386
解题思路:
题目大意:
给你n×n的初始图形,和目标图形,还有m个操作,操作和一把一行或一列变成一种颜色,现在问你使初始图形变成目标图形的操作
的顺序。每个操作都要用上,且一定有解。
算法思想:
初始图形是没有用的。直接从目标图形开始进行操作。对于一个操作,判断该操作对应的那一行或一列的颜色,是否除0之外全部都是与该操作变换的颜色相同,是的话,将那一行或一列全部变为0,并且记录该操作,最后逆序输出。注意,把所有操作遍历一遍是不够的,因为有一些操作是要在别的操作已进行过的基础上才能进行,所以在遍历操作的外层要再加一层循环,直到cnt == m为止。。。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 550;
struct node{
char op[3];
int x,y;
}no[maxn];
int color1[110][110];
int color2[110][110];
int vis[maxn];
int sta[maxn];
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",&color1[i][j]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d",&color2[i][j]);
for(int i = 1; i <= m; i++)
scanf("%s%d%d",no[i].op,&no[i].x,&no[i].y);
memset(vis,0,sizeof(vis));
int i,j,k;
int cnt = 0;
while(1){
for(i = 1; i <= m; i++){
if(vis[i])
continue;
if(no[i].op[0] == 'L'){
j = no[i].x;
for(k = 1; k <= n; k++){
if(color2[k][j] && color2[k][j] != no[i].y)
break;
}
if(k == n+1){
for(k = 1; k <= n; k++)
color2[k][j] = 0;
sta[++cnt] = i;
vis[i] = 1;
}
}
else{
j = no[i].x;
for(k = 1; k <= n; k++){
if(color2[j][k] && color2[j][k] != no[i].y)
break;
}
if(k == n+1){
for(k = 1; k <= n; k++)
color2[j][k] = 0;
sta[++cnt] = i;
vis[i] = 1;
}
}
if(cnt == m)
break;
}
if(cnt == m)
break;
}
for(i = cnt; i > 1; i--)
printf("%d ",sta[i]);
printf("%d\n",sta[1]);
}
return 0;
}