考虑搜索。
将每行,每列,每块的状态压缩,然后爆搜就可以了。
写起来比较质朴,老老实实敲完就可以了。
输入的时候处理信息需要一些技巧(参见代码中的now_l,now_p)
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 8 int cnet[90][90],vis[90][90]; 9 int mp[10][10]; 10 int lr[10],ud[10],bl[10]; 11 int bel[90]; 12 int flag=0; 13 int dr[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; 14 15 inline int id(int x,int y){ 16 return (x-1)*9+y; 17 } 18 inline int lb(int x){ 19 return x&(-x); 20 } 21 inline bool wall(int x,int y){ 22 if(x<1||y<1||x>9||y>9)return false; 23 return true; 24 } 25 inline bool check(int dx,int dy,int x,int y){ 26 if(wall(dx,dy)&&mp[dx][dy]&&cnet[id(dx,dy)][id(x,y)]!=-1)return true; 27 return false; 28 } 29 inline void dfs(int now){ 30 int idx=(now-1)/9+1,idy=((now-1)%9)+1; 31 if(now==82){ 32 flag=1;return; 33 } 34 int rest=lr[idx]&ud[idy]&bl[bel[now]]; 35 while(rest){ 36 int pos=lb(rest);rest-=pos; 37 pos=log2(pos)+1; 38 int unable=0; 39 for(int i=0;i<4;i++){ 40 int dx=idx+dr[i][0],dy=idy+dr[i][1]; 41 if(check(dx,dy,idx,idy)&&(pos>mp[dx][dy])!=cnet[now][id(dx,dy)]){ 42 unable=1;break; 43 } 44 } 45 if(unable)continue; 46 mp[idx][idy]=pos; 47 lr[idx]-=(1<<(pos-1));ud[idy]-=(1<<(pos-1));bl[bel[now]]-=(1<<(pos-1)); 48 dfs(now+1); 49 if(flag)return; 50 mp[idx][idy]=0; 51 lr[idx]|=(1<<(pos-1));ud[idy]|=(1<<(pos-1));bl[bel[now]]|=(1<<(pos-1)); 52 } 53 } 54 char ch[10]; 55 int now_l=1,now_p=0; 56 int main(){ 57 memset(cnet,-1,sizeof(cnet)); 58 for(int i=1;i<=15;i++){ 59 if(i%5==2||i%5==4){ 60 ++now_l; 61 for(int j=1;j<=9;j++){ 62 int x=id(now_l,j),y=x-9; 63 scanf("%s",ch+1); 64 cnet[x][y]=(ch[1]==‘^‘?1:0); 65 cnet[y][x]=cnet[x][y]^1; 66 } 67 } 68 else{ 69 now_p=0; 70 for(int j=1;j<=6;j++){ 71 ++now_p; 72 if(now_p%3==0)++now_p; 73 int x=id(now_l,now_p); 74 scanf("%s",ch+1); 75 cnet[x][x+1]=(ch[1]==‘>‘?1:0); 76 cnet[x+1][x]=cnet[x][x+1]^1; 77 } 78 } 79 if(i%5==0)++now_l; 80 } 81 for(int i=1;i<=9;i++){ 82 for(int j=1;j<=9;j++){ 83 int x=id(i,j); 84 bel[x]=(i-1)/3*3+(j-1)/3+1; 85 } 86 } 87 for(int i=1;i<=9;i++){ 88 lr[i]=ud[i]=bl[i]=(1<<9)-1; 89 } 90 dfs(1); 91 for(int i=1;i<=9;i++){ 92 for(int j=1;j<=9;j++){ 93 printf("%d ",mp[i][j]); 94 } 95 puts(""); 96 } 97 }
一个晚自习就改了一个题。
觉得挺值了吧,第一次写2^n以下的搜索。
“好呀,我A了,写了九十多行”(zzm写了200+)
zzm:“你看看你用了多少时间”
......
超生气的。
原文:https://www.cnblogs.com/chiyo/p/11178560.html