题解 P6226 [BalticOI 2019 Day1] 潜艇
cjh20090318 · · 题解
题解 P6226 [BalticOI 2019 Day1] 潜艇
题意
很清楚,忽略。
分析
看到这种字符串题很容易想到直接广度优先搜索,复杂度
很显然承受不了,所以考虑 DP。
状态设计
设
设命令字符串为
状态转移
初始状态
经过观察可以发现状态转移只需要两维,所以可以直接滚动省略掉第一维。
时间复杂度
发现 std::bitset 进行压位砍掉常数。
代码
//the code is from chenjh
#include<cstdio>
#include<bitset>
int r,c,m;
std::bitset<505> a[505],f[505],g[505];//a 为初始状态,f 为过程状态,g 为辅助状态。
int main(){
scanf("%d%d%d",&r,&c,&m);
for(int i=1;i<=r;i++){
scanf(" ");
for(int j=1;j<=c;j++) a[i][j]=getchar()=='.';
f[i]=a[i];
}
scanf(" ");
for(char c;m--;){
c=getchar();
if(c=='N'){
for(int i=1;i<r;i++)f[i]=f[i+1]&a[i];
f[r].reset();
}
else if(c=='S'){
for(int i=r;i>1;--i)f[i]=f[i-1]&a[i];
f[1].reset();
}
else if(c=='W'){
for(int i=1;i<=r;i++)f[i]=(f[i]>>1)&a[i];
}
else if(c=='E'){
for(int i=1;i<=r;i++)f[i]=(f[i]<<1)&a[i];
}
else if(c=='?'){
for(int i=1;i<=r;i++)g[i]=(f[i-1]|f[i+1]|(f[i]<<1)|(f[i]>>1))&a[i];
for(int i=1;i<=r;i++)f[i]=g[i];
}
else break;//直接转移即可。
}
int s=0;
for(int i=1;i<=r;i++)s+=f[i].count();//统计有多少个值为 1,即有多少个可行的点。
printf("%d\n",s);
return 0;
}