送情报

描述:

走迷宫,其中:

符号 消耗的时间 消耗的体力
. 1 1
w 2 2
m 3 1
x +∞ +∞
从S走到T,体力必须在0以上,求最短的时间

输入:

0 < N、M < 20

Map

P(体力)

输出:

ans

————————————————————集训5.2的分割线————————————————————

思路:只是增加了一种状态:体力,将其纳入vis数组当中即可。注意不要回到起点。找到T不要退出BFS,要搜完整个队列,维护一个时间最短的答案。

代码如下:

/*
ID: j.sure.1
PROG:
LANG: C++
*/
/****************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <iostream>
using namespace std;
/****************************************/
#define LIM (nx >= 0 && nx < n && ny >= 0 && ny < m)
const int N = 25;
int n, m, sx, sy, ex, ey, P, minX = 2e9;
const int d[][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
char mat[N][N];
bool vis[N][N][1205];
struct Node
{
	int x, y;
	int hp, step;
};
queue <Node> q;

void bfs()
{
	Node t;
	t.x = sx; t.y = sy; t.hp = P; t.step = 0;
	q.push(t);
	while(!q.empty()) {
		t = q.front();
		q.pop();
		for(int dd = 0; dd < 4; dd++) {
			Node nt;
			int &nx = nt.x = t.x + d[dd][0];
			int &ny = nt.y = t.y + d[dd][1];
			if(!LIM || mat[nx][ny] == 'x' || mat[nx][ny] == 'S')
				continue;
			int &np = nt.hp = t.hp, &ns = nt.step = t.step;
			bool ok = false;
			switch(mat[nx][ny])
			{
				case '.': np--; ns++; break;
				case 'w': np-=2; ns+=2; break;
				case 'm': np--; ns+=3; break;
				case 'T': np--; ns++; ok = true; break;
			}
			if(!vis[nx][ny][np] && np > 0) {
				vis[nx][ny][np] = true;
				q.push(nt);
//printf("[%d, %d]->[%d, %d] at hp = %d & t = %d\n", t.x, t.y, nx, ny, np, ns);
				if(ok) minX = min(minX, ns);
			}
		}
	}
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("Intelligence.in", "r", stdin);
//  freopen(".out", "w", stdout);
#endif
	while(~scanf("%d%d", &n, &m), n||m) {
		getchar();
		memset(vis, 0, sizeof(vis));
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < m; j++) {
				scanf("%c", &mat[i][j]);
				switch(mat[i][j])
				{
					case 'S': sx = i; sy = j; break;
					case 'T': ex = i; ey = j; break;
				}
			}
			getchar();
		}
		scanf("%d", &P);
		P = P < 1200 ? P : 1200;
		bfs();
		if(minX == 2e9)
			puts("No");
		else
			printf("%d\n", minX);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值