您的位置:首页 > 其它

【codeforces 516B】Drazil and Tiles

2017-09-02 10:33 281 查看

题目链接:

  http://codeforces.com/problemset/problem/516/B

题解:

  首先可以得到一个以‘.’为点的无向图,当存在一个点没有边时,无解。然后如果这个图边双联通无唯一解。

  同时观察可知,只有一条边的点只有唯一一种连法,所以我们可以直接将其与其相连点从图中删除,再考虑剩下图中是否还有只有一条边的点,直到所有的结点都被删除,或剩下双联通分量以及存在没有边的结点为止。

  正确性……显然吧。时间复杂度$O(n^{2})$。

代码:

  

#include<cstdio>
inline int read(){
int s=0,k=1;char ch=getchar();
while(ch<'0'||ch>'9')   k=ch=='-'?-1:k,ch=getchar();
while(ch>47&&ch<='9')   s=s*10+(ch^48),ch=getchar();
return s*k;
}
const int N=2010;
int n,m;
char map

;
char result

;
struct node {
int x,y;
};
node q[N*N];
int l,r;
int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
char z[8]={'^','v','<','>','v','^','>','<'};
int pan(int x,int y){
int ans=0;
for(int i=0;i<4;i++){
int nx=x+xx[i],ny=y+yy[i];
if(map[nx][ny]=='.')    ans++;
}
return ans;
}
inline bool solve(){
int sum=0;
for(int i =1;i<=n;i++)
for(int j=1;j<=m;j++){
if(map[i][j]=='*'){
result[i][j]=map[i][j];
continue;
}
sum++;
int t=pan(i,j);
if(t==0)    return 0;
else    if(t==1)    q[r++]=(node){i,j};
}
if(sum&1)   return false;
int t=0;
while(l<r){
node now=q[l++];
int x=now.x,y=now.y;
if(map[x][y]!='.')  continue;
for(int i=0;i<4;i++){
int nx=x+xx[i],ny=y+yy[i];
if(map[nx][ny]=='.'){
t++;
map[x][y]=0;
map[nx][ny]=0;
result[x][y]=z[i];
result[nx][ny]=z[i+4];
for(int j=0;j<4;j++){
int tx=nx+xx[j],ty=ny+yy[j];
if(map[tx][ty]=='.'){
int t=pan(tx,ty);
if(t==1)    q[r++]=(node){tx,ty};
if(t==0)    return false;
}
}
break;
}
if(i==3)    return false;
}
}
return t>=sum/2;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;result[i][m+1]='\n',i++)
scanf("%s",map[i]+1);
bool ans=solve();
// printf("\n");
if(ans){
for(int i=1;i<=n;i++)
for(int j=1;j<=m+1;j++){
printf("%c",result[i][j]);
}
}
else    printf("Not unique\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: