BOI Day1 nautilus 题解

题意:

按照给出的字符串的方向走后,最终可能处于多少个位置。

分析:

可以发现,每走一步就是对当前所有可能的位置统一进行一次移动,遇到障碍或超出边界就舍弃这个位置a。
如果我们给这个矩阵的每个位置附上一个编号,那么我们发现:上下左右移动一格等价于编号+1、-1、+C、-C。
所以,我们不难想到将矩阵表示为一个二进制的01串,如果当前可能到达这个位置,那么该处为1,否则为零。
一次移动等价于二进制的左移右移,遇到问号相当于将上下左右移动都做一遍的结果或起来;
遇到障碍或超出边界舍弃这个位置就相当于:这个二进制数对所有合法的位置&1,对所有非法的位置&0。
R*C<=2500,所以我们可以用bitset来实现这个操作,bitset的count()函数会返回二进制中1的个数。

一个实现上的细节:左右移动一格后可能会移到上一行的末尾和下一行的开头位置,为了避免这种情况,我们需要在矩阵边界处补上两列非法位置。

详见代码:

#include<cstdio>
#include<bitset>
using namespace std;
#define MAXN 5010
bitset<251000>a,s;
char t[MAXN];
int n,m,K;
int main()
{
	freopen("nautilus.in","r",stdin);
	freopen("nautilus.out","w",stdout);
	scanf("%d%d%d",&n,&m,&K);
	m+=2;
	for(int i=0;i<n;i++)
	{
		scanf("%s",t+1);
		for(int j=0;j<m;j++)
			if(t[j]=='.') s[i*m+j]=1;
	}
	a=s;
	scanf("%s",t);
	for(int i=0;i<K;i++)
	{
		if(t[i]=='?') a=((a>>1)|(a<<1)|(a>>m)|(a<<m))&s;
		else if(t[i]=='N') a=(a>>m)&s;
		else if(t[i]=='S') a=(a<<m)&s;
		else if(t[i]=='W') a=(a>>1)&s;
		else if(t[i]=='E') a=(a<<1)&s;
	}
	printf("%d\n",(int)a.count());
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值