搜索BFS


HDU 1175  连连看

http://acm.hdu.edu.cn/showproblem.php?pid=1175

//BFS

#include<cstdio>
#include<queue>
using namespace std;

bool flag;
int n,m,q,x1,y1,x2,y2;
int map[1005][1005];
int visit[1005][1005];
int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};  // 上下左右方向

struct node{
    int x, y;
    int dir[2];  // 用于保存上次走的方向
    int count;   // 已转弯的次数
}s,t;
queue<node>Q;

void BFS(){
    int i,j,temp=map[x2][y2];

    // 所点的两个数字不同、两次点同一个、点到了元素为0(没有棋子)的情况直接输出NO
    if((map[x1][y1]!=map[x2][y2]) || (x1==x2 && y1==y2) || (!map[x1][y1] || !map[x2][y2])){
        printf("NO\n");
        return;
    }
    // 如果点在外面的情况则不能,输出NO
    if(x1<0 || x1>=n || y1<0 || y1>=m || x2<0 || x2>=n || y2<0 || y2>=m){
        printf("NO\n");
        return;
    }

    // 初始化访问标记
    memset(visit,false,sizeof(visit));
    visit[x1][y1] = true;

    while(!Q.empty())
        Q.pop();
    s.x = x1, s.y=y1, s.dir[0]=s.dir[1]=0, s.count=0;
    Q.push(s);
    
    while(!Q.empty()){
        t=Q.front();
        Q.pop(); 
        for(i=0; i<4; ++i){
            s = t; 

            // 剪枝,如果转弯次数已经是2,目标不能不同行又不同列,且下一步的方向必须与上一次相同而不能转弯
             if(s.count==2 && (s.x!=x2 && s.y!=y2 || (s.dir[0]!=dir[i][0] || s.dir[1]!=dir[i][1])) )
                continue;

            s.x+=dir[i][0];
            s.y+=dir[i][1];
                 
            if((s.dir[0]!=dir[i][0] || s.dir[1]!=dir[i][1]) && s.dir[0]!=s.dir[1])
                ++s.count;
            s.dir[0] = dir[i][0], s.dir[1] = dir[i][1];
        
            if(s.count>2) 
                continue;
            
            if(s.x==x2 && s.y==y2){// 是否符合条件的
                if(s.count<=2){
                    printf("YES\n");
                    return;
                }
                continue;
            }
            //是否压入队列
            if(s.x>=0 && s.x<n && s.y>=0 && s.y<m && !visit[s.x][s.y] && !map[s.x][s.y]){
                visit[s.x][s.y] = true;
                Q.push(s);
            }    
        }
    }
    printf("NO\n");
}

int main()
{
   // freopen("input.txt","r",stdin);
    int i,j;
    while(scanf("%d %d",&n,&m)!=EOF){
        if(!n && !m)
            break;

        for(i=0; i<n; ++i)
            for(j=0; j<m; ++j)
                scanf("%d",&map[i][j]);

        scanf("%d",&q);
        while(q--){
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            --x1, --y1, --x2, --y2;
            BFS();
        }
    }
    return 0;
} 

HDU 1072  Nightmare


http://acm.hdu.edu.cn/showproblem.php?pid=1072

// BFS

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

int	dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int T,N,M,x1,y1,x2,y2;
int map[10][10], visit[10][10];  // visit存经过那个位置时所剩下的时间

struct node{
	int x,y;
	int count;  //  走过的步数
	int time;   //  用过的时间
}s,t;
queue<node>Q;

bool is_out(int x,int y,int time){
	if(x==x2 && y==y2 && time<6)
		return true;
	return false;
}

void BFS(){
 	memset(visit,6,sizeof(visit));   //  初始化为6, 如果用过的时间为6的话那么就不能再走了
  	visit[x1][y1] = 0;

	while(!Q.empty())
		Q.pop();
	s.x=x1, s.y=y1, s.count=0, s.time=0;
	Q.push(s);

	while(!Q.empty()){
		t = Q.front();
		Q.pop();
		if(is_out(t.x,t.y,t.time)){
			printf("%d\n",t.count);
			return;
		}
		for(int i=0; i<4; ++i){
			int dx = t.x+dir[i][0];
			int dy = t.y+dir[i][1];
			int dt = t.time+1;

			// dt<visit[dx][dy], 是表示如果这次到那个地方所用的时间比上次用的时间短,就可以再走
			if(dx>=0 && dx<N && dy>=0 && dy<M && map[dx][dy] &&  dt<visit[dx][dy]){  
			  	if(map[dx][dy] == 4 && dt<6)
					dt = 0;            
				visit[dx][dy] = dt;    //  标记为走到这步时用到的时间
				s.x=dx, s.y=dy, s.count=t.count+1, s.time=dt;
				Q.push(s);
			}
		}
	}
 	printf("-1\n");
} 

int main()
{
//	freopen("input.txt","r",stdin);

	int i,j;
	scanf("%d",&T);
	
	while(T--){
		scanf("%d %d",&N,&M);
		for(i=0; i<N; ++i){
			for(j=0; j<M; ++j){
				scanf("%d",&map[i][j]);
				if(map[i][j]==2)  //起始位置
					x1=i, y1=j;
				else if(map[i][j]==3)  //出口
					x2=i, y2=j;
			}
		}
		BFS();
	}
	return 0;
}

HDU 1241 Oil Deposits

http://acm.hdu.edu.cn/showproblem.php?pid=1241


/*
BFS题目,依次枚举,当遇到一个是'@'的,就通过广搜,把所有搜到的都做上标记

*/


#include<cstdio>
#include<queue>
using namespace std;

int m,n,num,cnt;
char map[105][105];

// 八个方向,刚开始就是因为忽略还有斜对角线,导致一直不能过,浪费了很多时间
int dir[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,-1},{-1,1}};

struct node{
	int x,y;
}s,t;
queue<node>Q;

void BFS(){
	if(!num){
		printf("0\n");
		return;
	}
	cnt=0;
	for(int i=0; i<m; ++i){
		for(int j=0; j<n; ++j){
			if(map[i][j]=='@'){
				s.x=i, s.y=j;
				Q.push(s);
				++cnt;
				map[i][j] = '*';
				while(!Q.empty()){
					t = Q.front();
					Q.pop();
					for(int k=0; k<8; ++k){
						int dx = t.x+dir[k][0];
						int dy = t.y+dir[k][1];
						if(dx>=0 && dx<m && dy>=0 && dy<n && map[dx][dy]=='@'){
							s.x = dx, s.y = dy;
							map[dx][dy] = '*';
							Q.push(s);
						}
					}
					
				}
			}
		}
	}
	printf("%d\n",cnt);
}

int main()
{
//	freopen("input.txt","r",stdin);

	int i,j;
	while(scanf("%d %d",&m,&n)!=EOF && m){
		
		num=0;
		memset(map,'*',sizeof(map));
		for(i=0; i<m; ++i){
			getchar();
			for(j=0; j<n; ++j){
				scanf("%c",&map[i][j]);
				if(map[i][j]=='@')
					++num;
			}
		}
		BFS();		 
	}
	return 0;
}

HDU 1241 rescue

http://acm.hdu.edu.cn/showproblem.php?pid=1242

#include<iostream>
#include<cstdio>
#include <memory.h> 
#include<queue>
using namespace std;

int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int map[205][205];
char a[205][205];

int N,M,x1,y1,x2,y2;
bool flag;

struct node{
	friend bool operator < (node a,node b){
		return a.step > b.step;   //优先步数少的
	}
	int x,y,step;
}n,m;

int main()
{
//	freopen("input.txt","r",stdin);

	int i,j;
	while(scanf("%d %d",&N,&M)!=EOF){

		for(i=0; i<N; ++i){
			getchar();
			for(j=0; j<M; ++j){
				scanf("%c",&a[i][j]);
				map[i][j] = 10000000; //初始化 
				if(a[i][j]=='r')
					x1=i,y1=j;
				else if(a[i][j]=='a')
					x2=i,y2=j;
			}
		}
		flag=false;
		n.x = x1;
		n.y = y1;
		n.step = 0;
		priority_queue<node>Q;  //建立优先队列
		Q.push(n);
		
		while(!Q.empty()){
			m = Q.top();
			Q.pop();
			if(m.x==x2 && m.y==y2){  //达到目标退出循环
				flag=true;
				break;
			}
			for(i=0; i<4; ++i){
				n.x = m.x+dir[i][0];
				n.y = m.y+dir[i][1];
				if(n.x>=0 && n.x<N && n.y>=0 && n.y<M && a[n.x][n.y]!='#'){
					if(a[n.x][n.y] == 'x')
						n.step = m.step+2;
					else
						n.step = m.step+1;
					if(n.step >= map[n.x][n.y])
						continue;
					map[n.x][n.y] = n.step;
					Q.push(n);
				}
			}
		}
		if(flag) printf("%d\n",m.step);
		else printf("Poor ANGEL has to stay in the prison all his life.\n");
	}
	return 0;
}




HDU 1253 胜利大逃亡

http://acm.hdu.edu.cn/showproblem.php?pid=1253

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

int K,A,B,C,T,x1,y1,z1;
int map[52][52][52];
bool visit[52][52][52];
int dir[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
struct node{
    int x,y,z;
    int count;
}s,temp;
queue<node>Q;

bool is_next(int x,int y,int z){
    if(x>=0 && x<A && y>=0 && y<B && z>=0 && z<C && !visit[x][y][z] && !map[x][y][z])
        return true;
    return false;
}

void BFS(){

    if(A+B+C>T){
        printf("-1\n");
        return;
    }

    while(!Q.empty())
        Q.pop();   // 确保队列为空

    memset(visit,false,sizeof(visit));  // 初始化访问标记
    visit[0][0][0] = true;   //所关地方标志为以走过
    s.x=0,s.y=0,s.z=0,s.count=0;
    Q.push(s);

    while(!Q.empty()){
        temp = Q.front();
        Q.pop();
        if(temp.x==A-1 && temp.y==B-1 && temp.z==C-1 && temp.count<=T){
            printf("%d\n",temp.count);
            return;
        }
        if(temp.count>T)
            break;
        for(int i=0; i<6; ++i){
            int x = temp.x+dir[i][0];
            int y = temp.y+dir[i][1];
            int z = temp.z+dir[i][2];
            if(is_next(x,y,z)){
                s.x = x, s.y=y, s.z=z, s.count=temp.count+1;
                visit[x][y][z] = true;
                Q.push(s);
            }
        }
    }
    printf("-1\n");
}

int main()
{
 //    freopen("input.txt","r",stdin);

    int i,j,k;
    scanf("%d",&K);
    while(K--){
        scanf("%d %d %d %d",&A,&B,&C,&T);
        for(i=0; i<A; ++i){
            for(j=0; j<B; ++j){
                for(k=0; k<C; ++k){
                    scanf("%d",&map[i][j][k]);
                }
            }
        }

        BFS();
    }
    return 0;
}

HDU 1312 Red and Black

http://acm.hdu.edu.cn/showproblem.php?pid=1312

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

int h,w,cnt,x1,y1;
char map[25][25];
bool visit[25][25];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
struct node{
	int x,y;
}s,q;
queue<node>qq;

void BFS(){
	cnt = 1;
	memset(visit,false,sizeof(visit));
	while(!qq.empty())
		qq.pop();
	visit[x1][y1] = true;
	s.x = x1, s.y = y1;
	qq.push(s);
	while(!qq.empty()){
		q = qq.front();
		qq.pop();
		for(int i=0; i<4; ++i){
			int dx = q.x+dir[i][0];
			int dy = q.y+dir[i][1];
			if(dx>=0 && dx<h && dy>=0 && dy<w && map[dx][dy]!='#' && !visit[dx][dy]){
				visit[dx][dy] = true;
				s.x = dx, s.y = dy;
				++cnt;
				qq.push(s);
			}
		}
	}
	printf("%d\n",cnt);
}

int main()
{
//	freopen("input.txt","r",stdin);

	int i,j;
	while(scanf("%d %d",&w,&h)!=EOF){
		if(!w && !h)
			break;
		for(i=0; i<h; ++i){
			getchar();
			for(j=0; j<w; ++j){
				scanf("%c",&map[i][j]);
				if(map[i][j]=='@')
					x1=i,y1=j;
			}
		}
		BFS();
	}
	return 0;
}

HDU 1026 Ignatius and the Princess I

http://acm.hdu.edu.cn/showproblem.php?pid=1026

#include<cstdio>
#include<queue>
using namespace std;

int N,M;
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
char map[105][105];
bool visit[105][105];

struct node{
	friend bool operator < (const node a, const node b){
		return a.cost>b.cost;
	}
	int x,y;
	int cost;
}a,b;

struct pathnode{
	int prex, prey;
}path[105][105];


// 倒着搜回去
void BFS(){
	memset(visit,false,sizeof(visit));
		visit[N-1][M-1] = true;
	path[N-1][M-1].prex = -1;  // 终点标记

	a.x=N-1, a.y=M-1, a.cost=0;
	//注意出口可能会有怪兽
	if(map[N-1][M-1] != '.')
		a.cost = map[N-1][M-1]-'0';

	priority_queue<node>Q;
	Q.push(a);
	
	while(!Q.empty()){
		b=Q.top();
		Q.pop();

		for(int i=0; i<4; ++i){
			a = b;
			a.x += dir[i][0];
			a.y += dir[i][1];

			// 超出范围的、'X'不能走的、走过的,直接跳过
			if(a.x<0 || a.x>=N || a.y<0 || a.y>=M || map[a.x][a.y]=='X' || visit[a.x][a.y])
				continue;
			visit[a.x][a.y] = true;

			// 处理这一格花了多少时间
			if(map[a.x][a.y] == '.')
				++a.cost;
			else 
				a.cost += map[a.x][a.y]-'0'+1;

			path[a.x][a.y].prex = b.x;
			path[a.x][a.y].prey = b.y;

			if(a.x==0 && a.y==0){
				printf("It takes %d seconds to reach the target position, let me show you the way.\n",a.cost);
			 	int x=a.x, y=a.y, key=1;
	 			while(path[x][y].prex != -1){
					int tx=path[x][y].prex;
					int ty=path[x][y].prey;
					printf("%ds:(%d,%d)->(%d,%d)\n",key++,x,y,tx,ty);
					if(map[tx][ty]!='.'){
						for(int j=0; j<map[tx][ty]-'0'; ++j)
							printf("%ds:FIGHT AT (%d,%d)\n",key++,tx,ty);
					} 
					x = tx;
					y = ty; 
				}    
				printf("FINISH\n");
				return;
			}		
			Q.push(a);
		}
	}
	printf("God please help our poor hero.\n");
	printf("FINISH\n");
}

int main()
{
//  freopen("input.txt","r",stdin);
	int i,j;
	while(~scanf("%d %d",&N,&M)){
		getchar();
		for(i=0; i<N; ++i){
			gets(map[i]);
		}
		BFS();
	}
	return 0;
}



——      生命的意义,在于赋予它意义。 

                   原创  http://blog.csdn.net/shuangde800  , By   D_Double





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值