【YbtOJ高效进阶 广搜-4】荆轲刺秦王

链接

YbtOJ高效进阶 广搜-4

题目描述

在这里插入图片描述
题目中的

样例输入 #1

5 4 0 0 5
. 1 T 1
. . . 2
. 1 . .
S . . .
1 . . .

样例输出 #1

3 0 0

样例输入 #2

8 6 2 3 3
. S . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
2 . 2 . 2 .
. . 1 . T .
3 . 1 . . 3

样例输出 #2

3 1 3

样例输入 #3

8 6 5 5 2
. S . . . .
. . . . . .
. . . . . .
1 1 3 2 . 1
2 3 2 2 1 3 
3 2 4 1 4 3 
2 6 1 5 T 2 
8 1 6 3 2 10

样例输出 #3

-1

思路

广搜,枚举八个方向以及闪现的四个方向,再加个判断隐身就可以了

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

int n, c1, c2, d, m, sx, sy, tx, ty, ans1, ans2, ans;
int b[505][505], Ans[505][505][26][26];
int dx[13] = {0, 0, 0, 1, -1, +1, +1, -1, -1};
int dy[13] = {0, 1, -1, 0, 0, -1, +1, +1, -1};
int d2[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1};
struct lL
{
	int x, y, c1, c2;
};

char read()
{
	char cc = getchar(), num = 0;
	while(cc != '.' && cc != 'S' && cc != 'T' && !(cc >= 48 && cc <= 65)) cc = getchar();
	if(cc == 'S') return -1;
	if(cc == 'T') return -2;
	else {
		while(cc >= 48 && cc <= 65) 
			num = num * 10 + cc - 48, cc = getchar();
		return num;
	} 
}//处理读入的数据

void chuli(int x, int y, int r)
{
	for(int i = 0; i <= r; ++i)
		for(int j = 0; j <= r - i; ++j)
		{
			if(x + i <= n && y + j <= m) b[x + i][y + j] = max(b[x + i][y + j], 1);
			if(x - i >= 1 && y + j <= m) b[x - i][y + j] = max(b[x - i][y + j], 1);
			if(x + i <= n && y - j >= 1) b[x + i][y - j] = max(b[x + i][y - j], 1);
			if(x - i >= 1 && y - j >= 1) b[x - i][y - j] = max(b[x - i][y - j], 1);
		}
	b[x][y] = 2;	
}//没用差分,直接将所有可以观测到的点标记

bool check(int x, int y, int c1, int c2)
{
	if(x < 1 || x > n || y < 1 || y > m || c1 < 0 || c2 < 0) return 0;
	if(Ans[x][y][c1][c2] > 0 || b[x][y] == 2) return 0;
	return 1;
}

void bfs()
{
	queue<lL>Q;
	Q.push((lL){sx, sy, c1, c2});
	while(Q.size())
	{
		int x = Q.front().x, y = Q.front().y, j1 = Q.front().c1, j2 = Q.front().c2;
		Q.pop();
		
		if (x == 3 && y == 5) {
			int aba;
			aba = 21;
		}
		
		for(int i = 1; i <= 12; ++i)
		{
			int nx = x + dx[i], ny = y + dy[i], ji1 = 0, ji2 = d2[i];
			if(b[nx][ny] == 1) ji1 = 1;//记录消耗次数
			if(check(nx, ny, j1 - ji1, j2 - ji2)) {
				Q.push((lL){nx, ny, j1 - ji1, j2 - ji2});
				Ans[nx][ny][j1 - ji1][j2 - ji2] = Ans[x][y][j1][j2] + 1;
			}
		}
	}
}

void outt()
{ 
	ans1 = ans2 = ans = 1e9;
	for(int i = 0; i <= c1; ++i)
		for(int j = 0; j <= c2; ++j)
			if(Ans[tx][ty][i][j] && (Ans[tx][ty][i][j] < ans || (Ans[tx][ty][i][j] == ans && i + j > ans1 + ans2) || (Ans[tx][ty][i][j] == ans && i + j == ans1 + ans2 && i > ans1))) {
				ans = Ans[tx][ty][i][j];
				ans1 = i;
				ans2 = j;
			}
	if(ans != 1e9) printf("%d %d %d", ans, c1 - ans1, c2 - ans2);
		else printf("-1");
}

int main()
{
	scanf("%d%d%d%d%d", &n, &m, &c1, &c2, &d);
	dx[9] = d; dx[10] = -d;
	dy[11] = d; dy[12] = -d;
	for(int i = 1; i <= n; ++i)
	for(int j = 1; j <= m; ++j)
	{
		int c = read();
		if(c == -1) sx = i, sy = j;
		if(c == -2) tx = i, ty = j;
		if(c > 0) chuli(i, j, c - 1);
	}
	bfs();
	outt();
	return 0;
}
购物商城项目采用PHP+mysql有以及html+css jq以及layer.js datatables bootstorap等插件等开发,采用了MVC模式,建立一个完善的电商系统,通过不同用户的不同需求,进行相应的调配和处理,提高对购买用户进行配置….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值