hdu:4771Stealing Harry Potter's Precious(bfs + 全排列)

题目:hdu:4771Stealing Harry Potter‘s Precious

题目大意:给出n* m的矩阵,代表n * m间room,然后每个房间又有脆弱和坚固之分,分别用‘.‘和‘#‘代替。’@‘代表Dudely所在的起点。

题目说Dudely想要偷Harry的宝物,他知道宝物的位置,但是他的魔法只能穿过脆弱的room。愚蠢的他又想偷完harry所有的宝物,并不在乎如何人出去。问最短移动的步数偷完所有的宝物。没法偷完所有的宝物就输出-1.

解题思路:这里要求的是最短路径问题。可以将各个宝物之间的最短距离和起点到每个宝物之间的最短距离都求出来,然后全排列能产生的路径,最后维护总距离的最小值。注意:如果在前面求最短距离的时候,发现有两个宝物或是宝物与起点是不可达的,那么就说明Dudely取不完所有的宝物,可以直接输出-1,后面的不用判断。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 105;
const int M = 5;
int n, m, Q;
char map[N][N];
int dist[N][N];
int ans[M][M];     //存放最短距离。
int mm;            //最短总距离
int vis[M];        

const int dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
const int INF = 0x6ffffff;

struct Precious {

	int x, y;
}precious[M], q[N * N];

int Min (const int x , const int y) {return x < y ? x: y;}
int bfs (const Precious begin, const Precious end) {

	memset (dist, 0, sizeof (dist));
	int front, rear;
	front = 0;
	rear = 1;
	q[front].x = begin.x;
	q[front].y = begin.y;
	while (front < rear) {

		if (q[front].x == end.x && q[front].y == end.y)
			return dist[q[front].x][q[front].y];
		for (int i = 0; i < 4; i++) {

			q[rear].x = q[front].x + dir[i][0];
			q[rear].y = q[front].y + dir[i][1];
			if (q[rear].x < 0 || q[rear].x >= n || q[rear].y < 0 || q[rear].y >= m)
				continue;
			if ( map[q[rear].x][q[rear].y] != '#' && !dist[q[rear].x][q[rear].y]) {

				dist[q[rear].x][q[rear].y] = dist[q[front].x][q[front].y] + 1;
				rear++;
			}
		}
		front++;
	}
	return -1;
}

bool solve () {

	memset (ans, -1, sizeof (ans));
	for (int i = 0; i <= Q; i++)
		for (int j = i + 1; j <= Q; j++) {

			ans[i][j] = ans[j][i] = bfs (precious[i], precious[j]);
			if (ans[i][j] == -1)
				return false;
		}

	return true;
}
/*
void dfs (int k, int x, int sum) {

	if (k == Q) {

		mm = Min (mm, sum);
		return;
	}

	for (int i = 1; i <= Q; i++) {

		if ( !vis[i] && ans[x][i]!= -1) {

			if (sum + ans[x][i] >= mm)
				return;
			vis[i] = 1;
			dfs (k + 1, i, sum + ans[x][i]);
			vis[i] = 0;
		}
	}
}
*/
void dfs () {

	int s[M];
	for (int i = 1; i <= Q; i++)
		s[i - 1] = i;
	sort (s, s + Q);
	int sum = 0;
	do {

		sum = ans[0][s[0]];
		for (int i = 0; i < Q - 1; i++)
			sum += ans[s[i]][s[i + 1]];
		mm = Min (mm, sum);
	} while (next_permutation (s, s + Q));
}

int main () {

	char ch;
	while (scanf("%d%d%c", &n, &m, &ch), n || m) {

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {

				scanf("%c", &map[i][j]);
				if (map[i][j] == '@') {

					precious[0].x = i;
					precious[0].y = j;
				}
			}
			scanf ("%c", &ch);
		}

		scanf("%d", &Q);
		for (int i = 1; i <= Q; i++) {

			scanf ("%d%d", &precious[i].x, &precious[i].y);
			precious[i].x--;
			precious[i].y--;
		}

		if (!solve())
			printf ("-1\n");
		else {

			mm = INF;
			memset(vis, 0, sizeof (vis));
			//dfs (0, 0, 0);
			dfs();
			printf ("%d\n", mm);
		}

	}
	return 0;
}

hdu:4771Stealing Harry Potter's Precious(bfs + 全排列)

时间: 2024-10-13 23:22:36

hdu:4771Stealing Harry Potter's Precious(bfs + 全排列)的相关文章

hdu 4771 Stealing Harry Potter&#39;s Precious (BFS+状压)

题意: n*m的迷宫,有一些格能走(“.”),有一些格不能走(“#”).起始点为“@”. 有K个物体.(K<=4),每个物体都是放在“.”上. 问最少花多少步可以取完所有物体. 思路: BFS+状压,看代码. 代码: struct node{ int x,s; node(int _x,int _s){ x=_x, s=_s; } }; int n,m,k,sx,sy; char graph[105][105]; int px[5],py[5]; int dp[105][105][35]; int

hdu 4771 Stealing Harry Potter&#39;s Precious(bfs)

题目链接:hdu 4771 Stealing Harry Potter's Precious 题目大意:在一个N*M的银行里,贼的位置在'@',现在给出n个宝物的位置,现在贼要将所有的宝物拿到手,问最短的路径,不需要考虑离开. 解题思路:因为宝物最多才4个,加上贼的位置,枚举两两位置,用bfs求两点距离,如果存在两点间不能到达,那么肯定是不能取完所有的宝物.然后枚举取宝物的顺序,维护ans最小. #include <cstdio> #include <cstring> #inclu

UVALive - 6455 Stealing Harry Potter&#39;s Precious (bfs+dfs)

https://cn.vjudge.net/problem/UVALive-6455 题目大意:题目上给出一个地图,其中@是人在地图上的出发点,#是墙,' . '是路.然后给出几个点,这些点表示财宝的所在地.问人是否能够得到所有的宝藏,如果能够的话给出所有的宝藏的最短的路径. 解题思路:由于只有最多4个宝藏所在地,所以只要用bfs找出出发点和财宝所在地距离到达其他点的步数.因为最多只有4个宝藏,所以可以暴力找出出发点到所有宝藏的最短距离. 暴力代码: 1 #include<stdio.h> 2

HDU 4771 Stealing Harry Potter&#39;s Precious dfs+bfs

Stealing Harry Potter's Precious Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his

【HDU 4771 Stealing Harry Potter&#39;s Precious】BFS+状压

2013杭州区域赛现场赛二水... 类似“胜利大逃亡”的搜索问题,有若干个宝藏分布在不同位置,问从起点遍历过所有k个宝藏的最短时间. 思路就是,从起点出发,搜索到最近的一个宝藏,然后以这个位置为起点,搜索下一个最近的宝藏,直至找到全部k个宝藏.有点贪心的感觉. 由于求最短时间,BFS更快捷,但耗内存,这道题就卡在这里了... 这里记录了我几次剪枝的历史...题目要求内存上限32768KB,就差最后600KB了...但我从理论上觉得已经不能再剪了,留下的结点都是盲目式搜索必然要访问的结点. 在此贴

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>

HDU 4771 Stealing Harry Potter&#39;s Precious (生成排列+枚举 + BFS)

Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1982    Accepted Submission(s): 931 Problem Description Harry Potter has some precious. For example, his invisib

hdu 4771 13 杭州 现场 B - Stealing Harry Potter&#39;s Precious 暴力bfs

Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his precious with him. As you know, uncle Ve

hdu 4771 Stealing Harry Potter&#39;s Precious (状态压缩+bfs)

Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1297    Accepted Submission(s): 619 Problem Description Harry Potter has some precious. For example, his invisib