1. 程式人生 > >【codeforces 516B】Drazil and Tiles

【codeforces 516B】Drazil and Tiles

以及 log and scan r+ com nbsp 題解 時間

題目鏈接:

  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 }

【codeforces 516B】Drazil and Tiles