UVa10047 BFS

题意:一自行车的轮子被分成5个扇区,涂了5种不同颜色。自行车每1秒要么骑到下一个格子,要么左转或者右转90。一开始自行车面向北,颜色为绿,到达目标格时,必须触底颜色为绿,但朝向无限制。求到达目标格的最短时间。

思路:可以朝3个方向搜索,多了一种颜色状态,每个结点有四个值需要保存,坐标x,坐标y,朝向,底面颜色。每个结点只可以执行一次,不然会出现死循环。所以需要vis数组标记。

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
const int maxn = 30;

struct node
{
	int x,y,s,c,dis;//x,y是坐标 s是方向 c是颜色 dis是距离
	node(int x = 0,int y = 0,int s = 0,int c = 0,int dis = 0):x(x),y(y),s(s),c(c),dis(dis){}
	bool operator < (const node &a) const
	{
		return a.dis < dis;
	}
};
char map[maxn][maxn];
int vis[maxn][maxn][4][5];
int n,m;
int d[4][2] = {-1,0,0,1,1,0,0,-1};

std::priority_queue<node> q;

int BFS(int sx,int sy,int ex,int ey)
{
	q.push(node(sx,sy,0,0,0));
	vis[sx][sy][0][0];
	node pp;
	while(!q.empty())
	{
		pp =q.top();
		q.pop();
		if(pp.x == ex && pp.y == ey && pp.c == 0)
		{
			return pp.dis;
		}
		for(int i=0;i<4;i++)
		{
			int dx = pp.x + d[i][0];
			int dy = pp.y + d[i][1];
			int dis = pp.dis+1;
			int c = (pp.c+1)%5;

			if(i == pp.s)
			{
				if(dx >= n || dx < 0 || dy < 0 || dy >= m)continue;
				if(map[dx][dy] == ‘#‘ || vis[dx][dy][pp.s][c]) continue;
				q.push(node(dx,dy,i,c,dis));
				vis[dx][dy][pp.s][c] = 1;
			}else
			{
				if((pp.s+1)%4 == i || (pp.s-1+4)%4 == i)
				{
					if(vis[pp.x][pp.y][i][pp.c])continue;
					vis[pp.x][pp.y][i][pp.c] = 1;
					q.push(node(pp.x,pp.y,i,pp.c,dis));
				}
			}
		}
	}

	return -1;
}
int main()
{
	int i,j;
	int sx,sy,ex,ey;
	int cas = 1;
	while(scanf("%d%d",&n,&m),n+m)
	{
		while(!q.empty())q.pop();
		memset(vis,0,sizeof(vis));
		for(i=0;i<n;i++)
		{
			scanf("%s",map[i]);
			for(j=0;j<m;j++)
			{
				if(map[i][j] == ‘S‘)
					sx = i, sy = j;
				if(map[i][j] == ‘T‘)
					ex = i, ey = j;
			}
		}
		if(cas > 1) printf("\n");
		printf("Case #%d\n",cas++);
		int ans = BFS(sx,sy,ex,ey);
		if(ans == -1) printf("destination not reachable\n");
		else printf("minimum time = %d sec\n",ans);
	}
	return 0;
}

/*

1 3
S#T
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
0 0

  */

UVa10047 BFS

时间: 2024-08-03 15:05:27

UVa10047 BFS的相关文章

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};

BFS+康托展开(洛谷1379 八数码难题)

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据) 输入样例#1: 2831

Sicily 1444: Prime Path(BFS)

题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 bool isPrime(int n){//素数判断 5 if(n == 2 || n == 3) return true; 6 else{ 7 int k = sqrt(n) + 1; 8 for(int i = 2; i < k; i

HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 524    Accepted Submission(s): 151 Problem Description TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams abou

POJ3967Ideal Path[反向bfs 层次图]

Ideal Path Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 1754   Accepted: 240 Description New labyrinth attraction is open in New Lostland amusement park. The labyrinth consists of n rooms connected by m passages. Each passage is colo

胜利大逃亡(续)(状态压缩bfs)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7357    Accepted Submission(s): 2552 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

邻接表实现Dijkstra算法以及DFS与BFS算法

//============================================================================ // Name : ListDijkstra.cpp // Author : fffff // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //==========================

图的两种遍历-DFS&amp;BFS

DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走,直到所有路都走完: struct node { int next; //E[i].next指向图中与i同父的下一个结点 int to; //E[i].to指向图中i的子结点 }E[110]; int N; int fa[110]; //记录各点的父结点 bool vis[110]; //记录这个点

POJ 2251 Dungeon Master (bfs)

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; char mat[50][50][50]; int vis[50][50][50]; int op[6][3]={0,-1,0, 0,1,0, 1,0,0, -1,0,0 ,0,0,1, 0,0,-1 }; int ok; in