Aizu0558 -- Chesse
作者:互联网
题意:
在H * W的地图上有N个奶酪工厂,每个工厂分别生产硬度为1-N的奶酪。有一只老鼠准备从出发点吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。 老鼠从当前格到上下左右相邻的无障碍物的格需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时
输入
第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, "."为空地, "X"为障碍物,"S"为老鼠洞,N表示有N个生产奶酪的工厂,硬度为1-N。
输出
输出一个整数,代表老鼠吃遍所有奶酪的最少时间花费。
输入样例
输入样例 1
3 3 1
S..
...
..1
输出样例1
4
输入样例 2
4 5 2
.X..1
....X
.XX.S
.2.X.
输出样例 2
12
输入样例 3
10 10 9
.X...X.S.X
6..5X..X1X
...XXXX..X
X..9X...X.
8.X2X..X3X
...XX.X4..
XX....7X..
X..X..XX..
X...X.XX..
..X.......
输出样例 3
91
解析:Bfs最短路问题.
值得一提的是:
- 这道题需要遍历n次最短路,从出发点 -> 硬度为1奶酪工厂最短路 -> 硬度为2奶酪工厂最短路 -> ... -> 硬度为3的奶酪工厂最短路。
- 在遍历图的时候,每一次bfs都要初始化所有路径为inf,这样可以判断这条路是否可达,或者之前是否走过,不过此题一定可以走完所有奶酪工厂,就不用担心不可以达的问题,而bfs第一次放入队列的数据肯定是该点的最短距离,所以之前走过,此时就不用再走。
- 是单独存放两个数据时可以用pair来存放,当存在两个多样类型数据时就可以封装成一个类,相对于结构数组美观一些。
第一次这么呕心沥血写注释...
AC代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<string.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> P; //用pair将两个数据合成一个数据(用结构体也可)
const int num = 1005;
const long long inf = 0x3f3f3f3f;
int h, w, n;
char maze[num][num]; //表示地图
int sx, sy; //起点坐标
int d[num][num]; //起点到该点的最短距离
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; //右下左上四个方向移动的向量
int res = 0; //最短时间
bool cp(int xx, int yy)
{
if(xx < 1 || xx > h || yy < 1 || yy > w) return false;
else return true;
}
void bfs(int bgx, int bgy, int tar) //起点坐标, 目标工厂的奶酪硬度
{
queue<P> q;
memset(d, 0x3f3f, sizeof(d)); //将所有起点到该点的最短距离初始化为INF
d[bgx][bgy] = 0; //起点到自身的距离为0
q.push(P(bgx, bgy));
//q.push(make_pair(bgx, bgy));
while(q.size())
{
P now = q.front(); //将队列的第一个元素取出
q.pop(); //将队列的第一个元素弹掉
int x = now.first, y = now.second; //将当前位置用x, y表示
if(maze[x][y] - '0' == tar)
{
//重新赋值起点位置, 也就是之前目标工厂的位置
sx = x;
sy = y;
res += d[x][y]; //加上这次走的时间(距离)
return;
}
for(int i = 0; i < 4; i++)
{
//下一次移动的位置坐标
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if(cp(xx, yy) && maze[xx][yy] != 'X' && d[xx][yy] == inf) //bfs第一次访问到的点一定是最短的
{
q.push(P(xx, yy)); //将其放入队列
d[xx][yy] = d[x][y] + 1; //到(xx, yy)的距离为到(x, y)距离 + 1
}
}
}
}
int main()
{
scanf("%d%d%d", &h, &w, &n);
getchar();
for(int i = 1; i <= h ;i++)
{
for(int j = 1; j <= w; j++)
{
scanf("%c", &maze[i][j]);
if(maze[i][j] == 'S')
{
sx = i;
sy = j;
}
}
getchar();
}
for(int i = 1; i <= n; i++)
bfs(sx, sy, i); //从起点走到硬度为1的工厂再走到硬度为N的工厂
printf("%d\n", res);
return 0;
}
标签:...,..,--,奶酪,yy,int,xx,Chesse,Aizu0558 来源: https://www.cnblogs.com/K2MnO4/p/13369940.html