[HDOJ 3638] Go , SuSu [模拟]

本文探讨了在充满挑战的地图环境中,如何运用AI算法成功从起点A到达终点B,同时避免与怪物相遇。通过直接模拟的方法,实现了在限定时间内完成任务的目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一个n*m的地图上(50*50),你要从点A走到点B,你可以在每个单位时间移动一个格子,也可以不移动。

地图上的格子分为可以行走的格子,和不可以行走的墙。

地图上还有k只怪物(50只),每个怪物可以看到自己前方的一块面积为9的区域。

怪物会每秒向前移动一个格子,如果碰到了墙壁或者走到了地图边缘,就会转身。

问你能否在1000秒内从A走到B,并且不被任何怪物看见?


解法:直接模拟即可,使用一个1000*50*50的数组记录每个时间点能否走到地图上的每个格子。然后再在每个时间点处理一下,将怪物能够看到的格子设定为不能走到。

复杂度:1000*50*50*5+1000*50*9


#include <cstdio>

const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char s[50][51];
int n,m,k;

inline bool in(int x,int y) {
	return x>=0&&x<n&&y>=0&&y<m&&s[x][y]!='*';
}
inline void putfalse(bool a[50][50],int x,int y) {
	if (in(x,y)) a[x][y]=false;
}
inline void puttrue(bool a[50][50],int x,int y) {
	if (in(x,y)) a[x][y]=true;
}
struct Monster {
	int x,y,d;
	void read() {
		scanf("%d%d%d",&x,&y,&d);
		x--;
		y--;
		d--;
	}
	void move() {
		x+=dir[d][0];
		y+=dir[d][1];
		if (!in(x,y)) {
			x-=dir[d][0];
			y-=dir[d][1];
			d^=1;
		}
	}
	void check(bool a[50][50]) {
		int x1=dir[d][0],y1=dir[d][1];
		int x2=dir[d^2][0],y2=dir[d^2][1];
		int x3=dir[d^3][0],y3=dir[d^3][1];
		putfalse(a,x,y);
		putfalse(a,x+x1,y+y1);
		putfalse(a,x+x1+x2,y+y1+y2);
		putfalse(a,x+x1+x3,y+y1+y3);
		putfalse(a,x+x1+x1,y+y1+y1);
		putfalse(a,x+x1+x1+x2,y+y1+y1+y2);
		putfalse(a,x+x1+x1+x3,y+y1+y1+y3);
		putfalse(a,x+x1+x1+x2+x2,y+y1+y1+y2+y2);
		putfalse(a,x+x1+x1+x3+x3,y+y1+y1+y3+y3);
	}
};

Monster a[50];
bool can[1001][50][50];

int cal() {
	for (int i=0;i<=1000;i++)
		for (int x=0;x<n;x++)
			for (int y=0;y<m;y++)
				can[i][x][y]=false;
	for (int x=0;x<n;x++)
		for (int y=0;y<m;y++)
			if (s[x][y]=='A') can[0][x][y]=true;
	for (int i=0;i<=1000;i++) {
		for (int j=0;j<k;j++)
			a[j].check(can[i]);
		for (int x=0;x<n;x++)
			for (int y=0;y<m;y++)
				if (s[x][y]=='B'&&can[i][x][y]) return i;
		if (i==1000) return -1;
		for (int j=0;j<k;j++)
			a[j].move();
		for (int x=0;x<n;x++)
			for (int y=0;y<m;y++)
				if (can[i][x][y]) {
					puttrue(can[i+1],x,y);
					puttrue(can[i+1],x+1,y);
					puttrue(can[i+1],x-1,y);
					puttrue(can[i+1],x,y+1);
					puttrue(can[i+1],x,y-1);
				}
	}
	return -1;
}
int main() {
	int t,tt,i;
	scanf("%d",&t);
	for (tt=1;tt<=t;tt++) {
		scanf("%d%d",&n,&m);
		for (i=0;i<n;i++) scanf("%s",s[i]);
		scanf("%d",&k);
		for (i=0;i<k;i++) a[i].read();
		int ans=cal();
		if (ans==-1) printf("Case %d: 胜败兵家事不期 卷土重来是大侠\n",tt);
		else printf("Case %d: %d\n",tt,ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值