P1815 蠕虫游戏
Augen_stern · · 题解
Part 1: 分析求解
题目的意思大致就是模拟一条蠕虫的活动,来观察它是否还活着。
算法的话直接暴力模拟就好了。
读题一直都很重要,请注意“棋盘的左上角为
为了方便叙述,本文 有点绕)
所以可以定义操作数组:
int dx[7]= {0,-1,0,1,0};
int dy[7]= {0,0,1,0,-1}; // 占位,N,E,S,W;
接着考虑第一种问题:“蠕虫撞上了自己”;
此时,我们可以通过两个数组分别来定义这个蠕虫的每一个身体节点,为每一个头,而因为这只蠕虫的长度恒为
预处理初始的身体节点:
int cnt=0,fg=0;
for(int i=11; i<=30; i++) {
headx[i-10]=25;
heady[i-10]=i;
map[25][i]=1; // 标记每一个身体节点。
cnt++;
}
int len=cnt;
在对于输入的字符串的每一位进行存储:
int f=0;
if(s[i]=='N') f=1;
else if(s[i]=='E') f=2;
else if(s[i]=='S') f=3;
else if(s[i]=='W') f=4;
cnt++;
headx[cnt]=headx[cnt-1]+dx[f];
heady[cnt]=heady[cnt-1]+dy[f];
tailx=headx[cnt-len+1];
taily=heady[cnt-len+1]; // len=20;
map[tailx][taily]=0; // 释放过去的尾巴标记。
此时,若蠕虫撞上了自己,则可以有:
if(map[headx[cnt]][heady[cnt]]==1) printf("The worm ran into itself on move %d.\n",i+1),fg=1;
然后考虑第二个问题,蠕虫出界了:
if(headx[cnt]>50||heady[cnt]>50||headx[cnt]<1||heady[cnt]<1) printf("The worm ran off the board on move %d.\n",i+1),fg=1;
这些时候,因为标记
直到最后还活着,就可以成功了:
if(fg) continue;
printf("The worm successfully made all %d moves.\n",n);
Part 2:CODE
所以就可以秒掉了,只需要注意每一次循环都要初始化:
#include<iostream>
#include<math.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define INF 0x7fffffff/2
using namespace std;
int n,tailx,taily;
int map[55][55];
int dx[7]= {0,-1,0,1,0};
int dy[7]= {0,0,1,0,-1};
int headx[200],heady[200];
int main() {
while(scanf("%d",&n)) {
if(n==0) break;
memset(map,0,sizeof(map));
memset(headx,0,sizeof(headx));
memset(heady,0,sizeof(heady)); // 初始化;
int cnt=0,fg=0;
for(int i=11; i<=30; i++) {
headx[i-10]=25;
heady[i-10]=i;
map[25][i]=1;
cnt++;
}
int len=cnt; // 预处理;
string s;
cin>>s;
for(int i=0; i<n; i++) {
int f=0;
if(s[i]=='N') f=1;
else if(s[i]=='E') f=2;
else if(s[i]=='S') f=3;
else if(s[i]=='W') f=4; // 找方向;
cnt++;
headx[cnt]=headx[cnt-1]+dx[f];
heady[cnt]=heady[cnt-1]+dy[f];
tailx=headx[cnt-len+1];
taily=heady[cnt-len+1]; // 储存节点;
map[tailx][taily]=0;
if(map[headx[cnt]][heady[cnt]]==1) printf("The worm ran into itself on move %d.\n",i+1),fg=1; // 第一种情况;
else if(headx[cnt]>50||heady[cnt]>50||headx[cnt]<1||heady[cnt]<1) printf("The worm ran off the board on move %d.\n",i+1),fg=1; // 第二种情况;
else map[headx[cnt]][heady[cnt]]=1;
if(fg) break;
}
if(fg) continue; // 直接下一组数据。
printf("The worm successfully made all %d moves.\n",n); // 苟到最后就是胜利。
}
return 0;
}
自给自足,丰衣足食!!!
2021.9.8 13:20 初稿成