【codeforces 516B】Drazil and Tiles

题目链接:

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

题解:

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

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

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

代码:

  

 1 #include<cstdio>
 2 inline int read(){
 3     int s=0,k=1;char ch=getchar();
 4     while(ch<'0'||ch>'9')   k=ch=='-'?-1:k,ch=getchar();
 5     while(ch>47&&ch<='9')   s=s*10+(ch^48),ch=getchar();
 6     return s*k;
 7 }
 8 const int N=2010;
 9 int n,m;
10 char map[N][N];
11 char result[N][N];
12 struct node {
13     int x,y;
14 };
15 node q[N*N];
16 int l,r;
17 int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
18 char z[8]={'^','v','<','>','v','^','>','<'};
19 int pan(int x,int y){
20     int ans=0;
21     for(int i=0;i<4;i++){
22         int nx=x+xx[i],ny=y+yy[i];
23         if(map[nx][ny]=='.')    ans++;
24     }
25     return ans;
26 }
27 inline bool solve(){
28     int sum=0;
29     for(int i =1;i<=n;i++)
30         for(int j=1;j<=m;j++){
31             if(map[i][j]=='*'){
32                 result[i][j]=map[i][j];
33                 continue;
34             }  
35             sum++;
36             int t=pan(i,j);
37             if(t==0)    return 0;
38             else    if(t==1)    q[r++]=(node){i,j};
39         }
40     if(sum&1)   return false;
41     int t=0;
42     while(l<r){
43         node now=q[l++];
44         int x=now.x,y=now.y;
45         if(map[x][y]!='.')  continue;
46         for(int i=0;i<4;i++){
47             int nx=x+xx[i],ny=y+yy[i];
48             if(map[nx][ny]=='.'){
49                 t++;
50                 map[x][y]=0;
51                 map[nx][ny]=0;
52                 result[x][y]=z[i];
53                 result[nx][ny]=z[i+4];
54                 for(int j=0;j<4;j++){
55                     int tx=nx+xx[j],ty=ny+yy[j];
56                     if(map[tx][ty]=='.'){
57                         int t=pan(tx,ty);
58                         if(t==1)    q[r++]=(node){tx,ty};
59                         if(t==0)    return false;
60                     }
61                 }
62                 break;
63             }
64             if(i==3)    return false;
65         }
66     }
67     return t>=sum/2;
68 }
69 int main(){
70     n=read(),m=read();
71     for(int i=1;i<=n;result[i][m+1]='\n',i++)
72         scanf("%s",map[i]+1);
73     bool ans=solve();
74    // printf("\n");
75     if(ans){
76         for(int i=1;i<=n;i++)
77             for(int j=1;j<=m+1;j++){
78                 printf("%c",result[i][j]);
79             }
80     }
81     else    printf("Not unique\n");
82 }

 

posted @ 2017-09-02 10:33  Troywar  阅读(138)  评论(0编辑  收藏  举报