关于一些BFS的题目:
ZOJ1438 : http://acm.zju.edu.cn/show_problem.php?pid=1438
一道最基础的BFS题,就是求在三维迷宫中从一个点到另外一个点的最短距离.
就是在输入的时候它不像以前那样先行再列最后层数,要小心
/*
* 简单的BFS
* 由于输入问题一开始WA了n次
*/
#include <iostream>
#include <deque>
#include <string>
using namespace std ;
struct Node
{
int x, y, z ;
}temp, t, aim ;
deque<Node> de[2] ;
bool mark[12][12][12] ;
char maze[12][12][12] ;
int Size, step ;
int walk[6][3] ;
bool operator ==(Node &a, Node &b)
{
if ( a.x == b.x && a.y == b.y && a.z == b.z ) return true ;
return false ;
}
void initi()
{
int i, j, k ;
for ( k = 0 ; k < Size ; k++ ) {
for ( j = 0 ; j < Size ; j++ ) {
getchar() ;
for ( i = 0 ; i < Size ; i++ ) {
scanf ( "%c", &maze[i][j][k] ) ;
mark[i][j][k] = false ;
}
}
}
scanf ( "%d%d%d", &temp.x, &temp.y, &temp.z ) ;
scanf ( "%d%d%d", &aim.x, &aim.y, &aim.z ) ;
mark[temp.x][temp.y][temp.z] = true ;
de[0].clear() ; de[1].clear() ;
de[0].push_back(temp) ;
step = 0 ;
}
void work()
{
int now = 0, n, i ;
while ( !de[0].empty() || !de[1].empty() ) {
n = now^1 ;
while ( !de[now].empty() ) {
temp = de[now].front() ;
de[now].pop_front() ;
if ( temp == aim ) {
printf ( "%d %d/n", Size, step ) ;
return ;
}
for ( i = 0 ; i < 6 ; i++ ) {
t.x = temp.x+walk[i][0] ;
t.y = temp.y+walk[i][1] ;
t.z = temp.z+walk[i][2] ;
if ( t.x < 0 || t.y < 0 || t.z < 0
|| t.x >= Size || t.y >= Size || t.z >= Size ) continue ;
if ( maze[t.x][t.y][t.z] == 'O' && !mark[t.x][t.y][t.z] ) {
mark[t.x][t.y][t.z] = true ;
de[n].push_back(t) ;
}
}
}
now = n ;
step ++ ;
}
printf ( "NO ROUTE/n" ) ;
}
void init()
{
walk[0][0] = 1 ; walk[0][1] = 0 ; walk[0][2] = 0 ;
walk[1][0] = 0 ; walk[1][1] = 1 ; walk[1][2] = 0 ;
walk[2][0] = 0 ; walk[2][1] = 0 ; walk[2][2] = 1 ;
walk[3][0] = -1 ; walk[3][1] = 0 ; walk[3][2] = 0 ;
walk[4][0] = 0 ; walk[4][1] = -1 ; walk[4][2] = 0 ;
walk[5][0] = 0 ; walk[5][1] = 0 ; walk[5][2] = -1 ;
}
int main ( void )
{
string str ;
init() ;
while ( cin >> str >> Size ) {
initi() ;
cin >> str ;
work() ;
}
return 0 ;
}
ZOJ2050 : http://acm.zju.edu.cn/show_problem.php?pid=2050
题目意思就是从输入状态一直换,知道矩阵中全是b状态或者全是w状态,换的方法是随便从矩阵中选一个值出来,和它相临的全部取反(包括它自己这个点也取反).
就是BFS从一个状态换到另外一个状态的最少步数,关键在于如何存状态,由于位数是确定的,所以想到用16位的位运算.
/*
* 0.07s BFS
*/
#include <iostream>
#include <deque>
using namespace std ;
deque<int> de[2] ;
int value[18], walk[5][2] ;
bool mark[65536] ;
int step ;
void initi()
{
int i, j ;
int num = 0 ;
char ch ;
for ( i = 0 ; i < 4 ; i++ ) {
while ( ch = getchar() ) {
if ( ch == 'b' || ch =='w' ) break ;
}
num = num << 1 ;
if ( ch == 'b' ) num ++ ;
for ( j = 0 ; j < 3 ; j++ ) {
ch = getchar() ;
num = num << 1 ;
if ( ch == 'b' ) num ++ ;
}
}
de[0].clear() ; de[1].clear() ;
de[0].push_back(num) ;
step = 0 ;
memset(mark,false,sizeof(mark)) ;
mark[num] = true ;
}
void work()
{
int now = 0, n, i, j, k ;
int temp ;
while ( !de[0].empty() || !de[1].empty() ) {
n = now^1 ;
while ( !de[now].empty() ) {
temp = de[now].front() ;
de[now].pop_front() ;
if ( temp == 0 || temp == 65535 ) { cout << step << endl ; return ; }
int x, y ;
for ( i = 0 ; i < 4 ; i++ ) {
for ( j = 0 ; j < 4 ; j++ ) {
x = temp ;
for( k = 0 ; k < 5 ; k++ ) {
int a = i+walk[k][0] ;
int b = j+walk[k][1] ;
if ( a < 0 || b < 0 || a >= 4 || b >= 4 ) continue ;
y = 16-(a*4+b) ;
if ( 1&(x>>y-1) ) {
x = ~x ;
x = x|value[y] ;
x = ~x ;
}
else x = x|value[y] ;
}
if ( !mark[x] ) { de[n].push_back(x) ; mark[x] = true ; }
}
}
}
now = n ;
step ++ ;
}
cout << "Impossible" << endl ;
}
void init()
{
walk[4][0] = 0 ; walk[4][1] = 0 ;
walk[0][0] = 1 ; walk[0][1] = 0 ;
walk[1][0] = 0 ; walk[1][1] = 1 ;
walk[2][0] = -1 ; walk[2][1] = 0 ;
walk[3][0] = 0 ; walk[3][1] = -1 ;