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;
}
—— 生命的意义,在于赋予它意义。