soj1111 Gnome Tetravex dfs搜索
来源:互联网 发布:fifaonline3国服数据库 编辑:程序博客网 时间:2024/06/05 17:34
这也是黑书上的一道例题。
先给个soj的链接:题目
【题目大意】
给定n*n(N<=5)个方块,每个方块由上下左右四个面构成。
问是否能将n*n个方块拼成任意两个相邻块的相邻面值相等。
实例如下图:
这是一个初始2*2的方块:
它可以拼成如下图形,满足要求:
分析:
这是个典型的搜索问题,属于约束性搜索。
搜索顺序从中间到两边能够比较快的剪掉一些枝。这里用bfs先计算出一个序列,再按照这个序列进行搜索。
由于可能存在完全相同的块,这里存储不同的块和每一块的数量。
通过dfs即可算出。
实事证明还是从头开始搜比较快= =
附个中间搜的代码如下:
#include <string.h>#include <stdio.h>#include <ctype.h>#include <algorithm>#include <queue>using namespace std;const int maxn = 32 ;int num , cnt[maxn] , nn , n , path[maxn] , order[maxn][6] , boundary[maxn][6] , sth ;bool vis[maxn] ;struct node { int top , right , bottom , left ;}block[maxn];inline bool get(int &t){ bool flag = 0 ; char c; while(!isdigit(c = getchar())&&c!='-') if( c == -1 ) break ; if( c == -1 ) return 0 ; if(c=='-') flag = 1 , t = 0 ; else t = c ^ 48; while(isdigit(c = getchar())) t = (t << 1) + (t << 3) + (c ^ 48) ; if(flag) t = -t ; return 1 ;}void dosth(int k){ queue<int> q; q.push(k/2*k); int x , y , i = 0 ; memset(vis,0,sizeof(vis)); while (!q.empty()) { boundary[i][k] = 0 ; x = order[i][k] = q.front(); q.pop(); if(vis[x]) continue; vis[x] = 1 ; if( x >= k ) q.push(x-k),boundary[i][k]^=1; if( x % k != 0 ) q.push(x-1),boundary[i][k]^=2; if( x % k != k-1 ) q.push(x+1),boundary[i][k]^=4; if( x / k < k-1 ) q.push(x+k),boundary[i][k]^=8; i++; }}void init(){ for( int i = 1 ; i <= 5 ; i++) dosth(i);}bool dfs(int pos){ if( pos == nn ) return true ; for ( int i = 1 ; i < num ; i++) if( cnt[i] ) { if( boundary[pos][n] & 1 && path[order[pos][n]-n] && block[path[order[pos][n]-n]].bottom != block[i].top ) continue; if( boundary[pos][n] & 2 && path[order[pos][n]-1] && block[path[order[pos][n]-1]].right != block[i].left ) continue; if( boundary[pos][n] & 4 && path[order[pos][n]+1] && block[path[order[pos][n]+1]].left != block[i].right ) continue; if( boundary[pos][n] & 8 && path[order[pos][n]+n] && block[path[order[pos][n]+n]].top != block[i].bottom ) continue; path[order[pos][n]] = i ; cnt[i]--; if(dfs(pos+1)) return 1 ; cnt[i]++; path[order[pos][n]] = 0 ; } return false ;}int main(){ int t , k , i , j ; init(); for ( k = 1 ; get(n) && n ; k++) { num = 1 ; nn = n * n ; sth = nn - n ; for( i = 0 ; i < nn ; i++) { get(block[num].top); get(block[num].right); get(block[num].bottom); get(block[num].left); for( j = 0 ; j < num ; j++) if( block[num].top == block[j].top && block[num].bottom == block[j].bottom && block[num].right == block[j].right && block[num].left == block[j].left ) break; if( j == num ) cnt[num++] = 1 ; else cnt[j]++; } memset(path,0,sizeof(path)); if(dfs(0)) printf("Game %d: Possible\n\n",k); else printf("Game %d: Impossible\n\n",k); }}
在附个zoj1008的代码
#include <string.h>#include <stdio.h>#include <ctype.h>#include <algorithm>#include <iostream>#include <queue>using namespace std;const int maxn = 232 ;int num , cnt[maxn] , nn , n , path[maxn] ;bool vis[maxn] ;struct node { int top , right , bottom , left ;}block[maxn];inline bool get(int &t){ bool flag = 0 ; char c; while(!isdigit(c = getchar())&&c!='-') if( c == -1 ) break ; if( c == -1 ) return 0 ; if(c=='-') flag = 1 , t = 0 ; else t = c ^ 48; while(isdigit(c = getchar())) t = (t << 1) + (t << 3) + (c ^ 48) ; if(flag) t = -t ; return 1 ;}const int cx[] = {1,-1,0,0};const int cy[] = {0,0,1,-1};bool dfs(int pos){ if( pos == nn ) return true ; int x = pos / n ; int y = pos % n ; for ( int i = 0 ; i < num ; i++) if( cnt[i] ) { if( x && block[path[pos-n]].bottom != block[i].top ) continue; if( y && block[path[pos-1]].right != block[i].left ) continue; path[pos] = i ; cnt[i]--; if(dfs(pos+1)) return 1 ; cnt[i]++; } return false ;}int main(){ int t , k , i , j ; for ( k = 1 ; get(n) && n ; k++) { num = 0 ; nn = n * n ; for( i = 0 ; i < nn ; i++) { get(block[num].top); get(block[num].right); get(block[num].bottom); get(block[num].left); for( j = 0 ; j < num ; j++) if( block[num].top == block[j].top && block[num].bottom == block[j].bottom && block[num].right == block[j].right && block[num].left == block[j].left ) break; if( j == num ) cnt[num++] = 1 ; else cnt[j]++; }bool ff = dfs(0);if(k>1)puts("");cout<<"Game "<<cases++<<": ";if(ff)cout<<"Possible"<<endl;else cout<<"Impossible"<<endl; }}
- soj1111 Gnome Tetravex dfs搜索
- ZOJ 2008 Gnome Tetravex 搜索(DFS)
- Gnome Tetravex dfs
- ZOJ1008 Gnome Tetravex DFS
- Gnome Tetravex (dfs)
- ZOJ1008 Gnome Tetravex(DFS)
- ZOJ1008 Gnome Tetravex(dfs)
- zju 1008 Gnome Tetravex dfs
- ZOJ 1008Gnome Tetravex DFS
- ZOJ 1008 Gnome Tetravex(DFS)
- zoj1008 gnome tetravex 很久之前的dfs
- ZOJ 1008(DFS+剪枝) Gnome Tetravex
- zoj 1008 Gnome Tetravex (dfs+剪枝)
- zoj 1008 Gnome Tetravex (DFS + 剪枝)
- ZOJ 1008 Gnome Tetravex (DFS + 剪枝)
- zoj 1008 Gnome Tetravex (dfs+枚举)
- ZOJ 1008 Gnome Tetravex(DFS)
- ZOJ--1008:Gnome Tetravex(剪枝dfs)
- StreamTokenizer的用法
- 我离开了Autodesk
- Android build error
- PHP,分页函数封装成类
- linux sz rz
- soj1111 Gnome Tetravex dfs搜索
- 硬盘数据恢复技巧总结
- Linux系统统计目录下的文件总数
- HTML5中添加多媒体支持(三)
- UltraEdit V18.10.1018 烈火绿色版
- 约瑟夫环问题
- ICS statusbar
- 终于明白这个LR寄存器了
- C++一个类所占字节问题讨论