您的位置:首页 > 其它

HDU 5386 Cover(暴力+逆推)——多校练习8

2015-08-14 09:39 375 查看


Cover

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Special Judge

Problem Description

You have an n∗n matrix.Every
grid has a color.Now there are two types of operating:

L x y: for(int i=1;i<=n;i++)color[i][x]=y;

H x y:for(int i=1;i<=n;i++)color[x][i]=y;

Now give you the initial matrix and the goal matrix.There are m operatings.Put
in order to arrange operatings,so that the initial matrix will be the goal matrix after doing these operatings

It's guaranteed that there exists solution.

 

Input

There are multiple test cases,first line has an integer T

For each case:

First line has two integer n,m

Then n lines,every
line has n integers,describe
the initial matrix

Then n lines,every
line has n integers,describe
the goal matrix

Then m lines,every
line describe an operating

1≤color[i][j]≤n
T=5
1≤n≤100
1≤m≤500

 

Output

For each case,print a line include m integers.The
i-th integer x show that the rank of x-th operating is i

 

Sample Input

1
3 5
2 2 1
2 3 3
2 1 3
3 3 3
3 3 3
3 3 3
H 2 3
L 2 2
H 3 3
H 1 3
L 2 3

 

Sample Output

5 2 4 3 1

 

Source

2015 Multi-University Training Contest 8

 
/*********************************************************************/

题意:有两类操作:①L x y 把矩阵的第x列涂成同一种颜色y;②H x y 把矩阵的第x行涂成同一种颜色y

给你n*n的初始矩阵、目标矩阵和m种操作,问如何安排操作顺序,使得初始矩阵能够转换成目标矩阵。
放上出题人的题解报告



正如上述所说,初始矩阵是没有用处的

解题思路:逆向思维 

枚举每个操作,然后判断该操作是不是最后一个操作。(就像撕胶布一样,一条一条的剥离)

判断是否是最后一个操作的方法是:

除去已经用过的点(即标记成0的点,可以充当任何颜色),如果操作的那一排都等于当前操作的颜色,那就是最后一个操作。然后再把操作过的点给标记,重复m次。

最后逆向输出记录下的操作的编号即可。

若有疑问的地方,欢迎指出,谢谢!

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 105;
const int inf = 1000000000;
const int mod = 258280327;
int c

,a[5*N],s[5*N][2],x[5*N],y[5*N];
int main()
{
int t,n,m,i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&c[i][j]);//初始矩阵
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&c[i][j]);//目标矩阵
for(i=1;i<=m;i++)
scanf("%s%d%d",s[i],&x[i],&y[i]);//操作
k=0;
while(m>k)
for(i=1;i<=m;i++)
if(x[i])
if(s[i][0]=='L')//列操作
{
for(j=1;j<=n;j++)
if(c[j][x[i]]&&c[j][x[i]]!=y[i])//若一列存在多种颜色,跳出
break;
if(j>n)//一列全为一种颜色,将其标记成0,可充当任何颜色
{
a[k++]=i;
for(j=1;j<=n;j++)
c[j][x[i]]=0;
x[i]=0;
}
}
else//行操作
{
for(j=1;j<=n;j++)
if(c[x[i]][j]&&c[x[i]][j]!=y[i])//若一行存在多种颜色,跳出
break;
if(j>n)//一行全为一种颜色,将其标记成0,可充当任何颜色
{
a[k++]=i;
for(j=1;j<=n;j++)
c[x[i]][j]=0;
x[i]=0;
}
}
for(i=k-1;i>0;i--)
printf("%d ",a[i]);
printf("%d\n",a[i]);
}
return 0;
}菜鸟成长记
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: