贪吃蛇

疫情期间学习算法新生赛 - K 贪吃蛇

Problem:K
Time Limit:1000ms
Memory Limit:165535K

Description

Void_Monitor喜欢玩贪吃蛇,但是他很菜,现在他请你来帮忙。 给你一个a*a的正方形地图,第i行第j列的坐标为[I,j],贪吃蛇的初始长度为2,蛇头和蛇尾分别在坐标[1,2]、[1,1]处,初始运动方向为向右,初始时间为第0秒,贪吃蛇每秒会向运动方向移动一格。
现在有2种操作:
1 x y:表示Void_Monitor在第x秒按下了y键,y为LURD中的一种,分别表示Void_Monitor按下了左、上、右、下四种按钮。注意,如果按键方向和蛇头方向相同或相反时,蛇的运动方向不变,否则蛇的运动方向会从第x秒开始转向按键方向。
2 x:蛇在第x秒时吃到了果实,蛇的长度+1 需要说明的是:当蛇在第x秒转向时,蛇会先转向再进行运动;当蛇在第x秒吃到了果实时,蛇会先运动再在尾部运动轨迹方向上增加长度。另外,如果在贪吃蛇在一次运动后蛇头碰到蛇身,或者蛇上任意一点的坐标不在地图范围内,则视为贪吃蛇死亡,贪吃蛇将一直保持死亡前的位置。
请你输出第m秒过后贪吃蛇的位置。
在这里插入图片描述
图中为a=10时的地图以及初始状态蛇的位置和运动方向。

Input

第一行一个整数a。第二行两个整数n和m。接下来是n行,每行第一个数为 opt,表示操作编号。接下来的输入的变量与操作编号对应。题目保证操作按时间顺序给出,且每1秒最多只有1个操作,数据范围(2<=a<=100;1<=x,m,n<=10000,1<=opt<=2)。

Output

10行,每行10列,即第m秒过后的地图,蛇所在的位置输出’o’,其余位置输出’.’,以换行结尾

Sample Input

样例输入1:

10
10 20
2 1 
2 2 
2 3 
2 4
2 5
1 6 R 
1 7 D 
1 8 L 
1 9 U 
2 10 

样例输入2:

10
12 20
2 1
2 2
2 3
2 4
2 5
2 6
1 7 D
1 9 L
1 11 U
1 13 R
1 15 D
1 17 L
Sample Output

样例输出1:

...ooooo..
......oo..
..........
..........
..........
..........
..........
..........
..........
..........

样例输出2:

......oo..
.......o..
...ooooo..
..........
..........
..........
..........
..........
..........
..........
Hint

对于样例1,贪吃蛇在第9秒过后就死亡了,因此最后贪吃蛇保持的是死亡前(第8秒过后)的位置

Tips

一道巨麻烦的毒瘤模拟题。
注意:数据还存在 m<x 的情况。

Code

#include <bits/stdc++.h>
using namespace std;

queue <pair<int,int>>q;
char mp[101][101],pos;
int a,n,m,death=0,opt,t=0,ot;
int hx,hy,cx=0,cy=1,tx,ty;

void go(int step)
{
	for(int i=0;i<step;i++)
	{
		hx+=cx;
		hy+=cy;
		if(hx>=1&&hx<=a&&hy>=1&&hy<=a)
		{
			tx=q.front().first;
			ty=q.front().second;
			mp[tx][ty]='.';
			q.pop();
			if(mp[hx][hy]=='o')
			{
				mp[tx][ty]='o';
				death=1;
				return;
			}
			mp[hx][hy]='o';
			q.push({hx,hy});
		}
		else death=1;
	}
}

void eat(int time)
{
	if(death)return;
	go(time-t-1);
	t=time;
	hx+=cx;
	hy+=cy;
	if(hx>=1&&hx<=a&&hy>=1&&hy<=a)
	{
		if(mp[hx][hy]=='o')
		{
			death=1;
			return;
		}
		q.push({hx,hy});
		mp[hx][hy]='o';
		tx=q.front().first;
		ty=q.front().second;
	}
	else death=1;
}

void turn(int time,char p)
{
	go(time-t-1);
	if(p=='L'&&!cy)cy=-1,cx=0;
	else if(p=='R'&&!cy)cy=1,cx=0;
	else if(p=='U'&&!cx)cx=-1,cy=0;
	else if(p=='D'&&!cx)cx=1,cy=0;
	t=time;
	hx+=cx;
	hy+=cy;
	if(hx>=1&&hx<=a&&hy>=1&&hy<=a)
	{
		tx=q.front().first;
		ty=q.front().second;
		mp[tx][ty]='.';
		q.pop();
		if(mp[hx][hy]=='o')
		{
			mp[tx][ty]='o';
			death=1;
			return;
		}
		q.push({hx,hy});
		mp[hx][hy]='o';
	}
	else death=1;
}

void prm()
{
	for(int i=1;i<=a;i++)
	{
		for(int j=1;j<=a;j++)
		{
			printf("%c",mp[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	memset(mp,'.',sizeof(mp));
	q.push({1,1});
	q.push({1,2});
	mp[1][1]=mp[1][2]='o';
	hx=1,hy=2;
	scanf("%d",&a);
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&opt);
		if(opt==2)
		{
			scanf("%d",&ot);
			if(ot>m&&!death)go(m-t);
			else if(!death)eat(ot);
		}
		else
		{
			scanf("%d %c",&ot,&pos);
			if(ot>m&&!death)go(m-t);
			else if(!death)turn(ot,pos);
		}
	}
	if(ot>m&&!death)go(m-t);
	else if(!death)go(m-t);
	prm();
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值