现在要用1×2的骨牌铺满n×m 方格中空的地方。
这些骨牌只能铺在空的地方并且不能重叠。
如果有唯一解,输出方案,如果没有解或者有多解输出Not unique
样例解释:
第一个样例中,有两种解:
1
2
3
<
>^
^*v
v
<
>
和
1
2
3
^
<
>
v*^
<
>v
所以答案是Not unique。
Input
单组测试数据。 第一行有两个整数 n 和m (1≤n,m≤2000). 接下来n行,每一行有m个字符,字符'.'表示空格子,'*'表示已经满的格子。
Output
如果没有解或者多解输出Not unique。 如果是唯一解,就输出那个解。用"<>" 表示横放的骨牌,用"^v"表示竖放的骨牌。看样例获得更多信息。
Input示例
样例输入1 3 3 ... .*. ... 样例输入2 4 4 ..** *... *.** ....
Output示例
样例输出1 Not unique 样例输出2 <>** *^<> *v** <><>
题解:
有点拓扑排序的味道
找到唯一能够覆盖的,然后盖上去,找找到下一个度数为1的。
然后搞一搞就好了。
代码(有两个点会超时,谨慎食用):
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
struct aaa{
int l1,r1;
}q[4000001];
char s1[5],s2[5],a[2002][2002],ans[2002][2002];
int b[2002][2002],bb[5],cc[5];
void bfs(int ll,int rr){
int l=0,r=1,t,k,i,ii,x,y,u,v;
q[1].l1=ll;q[1].r1=rr;
while(l<r){
l++;
u=q[l].l1;v=q[l].r1;
b[u][v]=0;
for(i=1;i<=4;i++){
x=u+bb[i];y=v+cc[i];
if(b[x][y]==0)continue;
b[x][y]=0;
ans[u][v]=s1[i];ans[x][y]=s2[i];
for(ii=1;ii<=4;ii++){
t=x+bb[ii];k=y+cc[ii];
if(b[t][k])b[t][k]--;
if(b[t][k]==1){
r++;
q[r].l1=t;q[r].r1=k;
}
}
}
}
}
int main(){
int n,m,i,j,x,y,flag=0,ii;
char s[10000];
s1[1]='<';s1[2]='>';s1[3]='^';s1[4]='v';
s2[1]='>';s2[2]='<';s2[3]='v';s2[4]='^';
bb[1]=0;bb[2]=0;bb[3]=1;bb[4]=-1;
cc[1]=1;cc[2]=-1;cc[3]=0;cc[4]=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%s",&s);
for(j=1;j<=m;j++)a[i][j]=s[j-1];
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(a[i][j]=='.'){
for(ii=1;ii<=4;ii++){
x=i+bb[ii];y=j+cc[ii];
if(a[x][y]=='.')b[i][j]++;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(b[i][j]==1)bfs(i,j);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(a[i][j]=='.'&&ans[i][j]==0){
flag=1;
break;
}
if(flag)printf("Not unique");
else{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(!ans[i][j])ans[i][j]='*';
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)printf("%c",ans[i][j]);
printf("\n");
}
}
}