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; }
// 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; }
/* 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; }
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; }
#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; }
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; }
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; }