因为出发点是在左下角,每次只能右转,所以走的一定是个顺时针,不能走已走过的位置限制了剩余能走的区域一定是个矩形
f[l][r][d][u][0 to 3]
表示当前能走的矩形区域的四条边的位置和当前的方向,因为矩形确定了,方向确定了,当前位置其实也就确定了所以不用记录当前位置
数组开不下这么大,但注意到按照dp的顺序,l是递增的,可以滚动掉这一维
转移时每次走一次走到转向,维护4个方向的前缀和,预处理每个位置4个方向第一个障碍
感觉很不好写呀qwq
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 105;
int mod;
inline void add(int &a,int b){a+=b;if(a>=mod)a-=mod;}
inline void dec(int &a,int b){a-=b;if(a<0)a+=mod;}
int n,m,edx,edy;
int ok[maxn][maxn];
char str[maxn];
int To[maxn][maxn][4];
void preto()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
To[i][j][3]=To[i][j-1][3];
if(!ok[i][j]) To[i][j][3]=j;
}
To[i][m+1][1]=m+1;
for(int j=m;j>=1;j--)
{
To[i][j][1]=To[i][j+1][1];
if(!ok[i][j]) To[i][j][1]=j;
}
}
for(int j=1;j<=m;j++)
{
To[n+1][j][2]=n+1; if(j==1) To[n+1][j][2]=n+2;
for(int i=n;i>=1;i--)
{
To[i][j][2]=To[i+1][j][2];
if(!ok[i][j]) To[i][j][2]=i;
}
for(int i=1;i<=n;i++)
{
To[i][j][0]=To[i-1][j][0];
if(!ok[i][j]) To[i][j][0]=i;
}
}
}
// 0 up
// 1 right
// 2 down
// 3 left
int f[2][maxn][maxn][maxn][4];
int sum[maxn][maxn][maxn];
int s[maxn][maxn][maxn][4];
int re;
int main()
{
scanf("%d%d%d",&n,&m,&mod);
scanf("%d%d",&edx,&edy);
for(int i=1;i<=n;i++)
{
scanf("%s",str+1);
for(int j=1;j<=m;j++) ok[i][j]=(str[j]=='+');
}
preto();
if(edx==1) return printf("%d\n",To[edy][edx][2]<=n?0:1),0;
int now=0;
for(int d=1;d<=n;d++) s[m][d][n][0]=1;
for(int l=2;l<=edx+1;l++)
{
now=!now;
for(int r=m;r>=l-1;r--) for(int d=1;d<=n;d++) for(int u=d;u<=n;u++)
{
s[r][d][u][1]=s[r+1][d][u][1];
int &tmp=f[now][r][d][u][1]; tmp=0;
if(To[d][l-1][2]>u+1)
{
tmp=s[r][d][u][0];
add(s[r][d][u][1],tmp);
if(l-1==edx&&d==edy) add(re,tmp);
}
}
for(int r=l;r<=m;r++) for(int d=2;d<=n+1;d++) for(int u=n;u>=d-1;u--)
{
s[r][d][u][2]=s[r][d][u+1][2];
int &tmp=f[now][r][d][u][2]; tmp=0;
if(To[d-1][r][3]<l-1)
{
tmp=s[r][d-1][u][1];
add(s[r][d][u][2],tmp);
if(r==edx&&d-1==edy) add(re,tmp);
}
}
for(int r=l-1;r<=m-1;r++) for(int d=1;d<=n;d++) for(int u=d;u<=n;u++)
{
int &tmp=f[now][r][d][u][3]; tmp=0;
if(To[u][r+1][0]<d-1)
{
tmp=s[r+1][d][u][2];
add(sum[r][d][u],tmp);
if(r+1==edx&&u==edy) add(re,tmp);
}
}
for(int r=l;r<m;r++) for(int d=1;d<=n;d++) for(int u=d-1;u<=n-1;u++)
{
s[r][d][u][0]=s[r][d-1][u][0];
int &tmp=f[now][r][d][u][0]; tmp=0;
if(To[u+1][l][1]>r+1)
{
tmp=sum[r][d][u+1];
add(s[r][d][u][0],tmp);
if(l==edx&&u+1==edy) add(re,tmp);
}
}
}
printf("%d\n",re);
return 0;
}