http://codeforces.com/contest/515/problem/D
题意:
题目意思:输入一个n*m包括'*'和'.'的矩阵,'.'表示该位置为空。'*'表示该位置已有东西。用一个1*2的瓷砖去填满空位置,如果只有一种方法,输出该方法。如果无解或有2种以上的方法输出Not unique.
思路:题目简化成只要求我们求 存在且填法唯一的答案。
那么我们就从这个唯一入手, 如果一个空节点(也就是点)的度数为一(也就是周围只有1个空节点),那么我们就先填他,因为他的填法是唯一的,
并且填了它之后,我们要更新它隔壁的那一个刚被填掉的瓷砖的周围的点的度数,如果发现有度数为1的点,则push进队列
*******当队列为空之后,就是把所有 能够确定的唯一填法的瓷砖都填完了 接下来把图扫描一遍即可,如果还有空瓷砖,表示不能填满 或者 有多种方式填, 否则就是合法唯一答案
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int n,m;
struct node
{
int x,y;
node(){}
node(int a,int b)
{
x=a;y=b;
}
};
char tm[2005][2005];
queue <node> q;
int cal(int i,int j)
{
int cun=0;
if (i-1>=1 &&tm[i-1][j]=='.')
cun++;
if (i+1<=n &&tm[i+1][j]=='.')
cun++;
if (j-1>=1 &&tm[i][j-1]=='.')
cun++;
if (j+1<=m &&tm[i][j+1]=='.')
cun++;
return cun;
}
int c_dir(node t)
{
int i=t.x;
int j=t.y;
if (j-1>=1 &&tm[i][j-1]=='.')
return 1;
if (i-1>=1 &&tm[i-1][j]=='.')
return 2;
if (j+1<=m &&tm[i][j+1]=='.')
return 3;
if (i+1<=n && tm[i+1][j]=='.')
return 4;
return 0; //注意不要漏掉
}
void change(node t)
{
int i=t.x;
int j=t.y;
if (i-1>=1 &&cal(i-1,j)==2&&tm[i-1][j]=='.')
q.push(node(i-1,j));
if (i+1<=n &&cal(i+1,j)==2&&tm[i+1][j]=='.')
q.push(node(i+1,j));
if (j-1>=1 &&cal(i,j-1)==2&&tm[i][j-1]=='.')
q.push(node(i,j-1));
if (j+1<=m &&cal(i,j+1)==2&&tm[i][j+1]=='.')
q.push(node(i,j+1));
}
int main()
{
int i ,j;
scanf("%d%d",&n,&m);
getchar();
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
scanf("%c",&tm[i][j]);
}
getchar();
}
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
if (tm[i][j]=='*') continue;
if (cal(i,j)==1)
q.push(node(i,j));
}
}
// printf("size:%d\n",q.size());
while(!q.empty())
{
node t=q.front();
q.pop();
int dir=0;
dir=c_dir(t);
if (dir==1)
{
change(node(t.x,t.y-1));
tm[t.x][t.y]='>';
tm[t.x][t.y-1]='<';
}
if (dir==2)
{
change(node(t.x-1,t.y));
tm[t.x][t.y]='v';
tm[t.x-1][t.y]='^';
}
if (dir==3)
{
change(node(t.x,t.y+1));
tm[t.x][t.y]='<';
tm[t.x][t.y+1]='>';
}
if (dir==4)
{
change(node(t.x+1,t.y));
tm[t.x][t.y]='^';
tm[t.x+1][t.y]='v';
}
}
int flag=0;
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
if( tm[i][j]=='.' )
{flag=1;break;}
}
}
if (flag)
printf("Not unique\n");
else
{
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
printf("%c",tm[i][j]);
}
printf("\n");
}
}
return 0;
}

本文解析了CodeForces竞赛中一道关于填充1x2瓷砖的题目,通过寻找度数为1的空节点来确定唯一填法,并给出了实现代码。

506

被折叠的 条评论
为什么被折叠?



