Description
给定一个 n∗ m 的网格,你在左下角 (n,1),你只能往前走或者右拐,障碍和走过的点不能走。求走到 (y,x) 的方案数 mod k 的值。
Input
第一行输入 n,m,k (n,m ≤ 100,k ≤ 10^9 )。第二行输入 x,y,意这里是x 列 y 行,以下 n 行 m 行的字符矩阵 + 表示可以走, * 表示障碍。
Output
输出一个数,表示方案数 mod k 的值。
Sample Input
3 5 10 4 2 +++++ ++*++ ++++*
Sample Output
2
Data Constraint
n,m ≤ 100,k ≤ 10^9.
Solution
Code
#include<cstdio>
#include<cstring>
#define I int
#define F(i,a,b) for(register int i=a;i<=b;++i)
#define mem(a,b) memset(a,b,sizeof a)
#define N 102
using namespace std;
I n,m,X,Y,p,s,f[2][N][N][N][4],lf[N][N],up[N][N];
char c;
I main(){
scanf("%d%d%lld\n%d%d\n",&n,&m,&p,&Y,&X);
F(i,1,n){
F(j,1,m){
scanf("%c",&c);
lf[i][j]+=lf[i][j-1]+(c=='*');
up[i][j]+=up[i-1][j]+(c=='*');
}
scanf("\n");
}
F(d,0,n+m-2){
s^=1;
for(I i=X;i&&X-i<=d;i--){
for(I j=Y;j&&Y-j+X-i<=d;j--){
for(I k=X;k<=n&&k-i+Y-j<=d;k++){
I l=d+i+j-k;
if(l>m) continue;
f[s][i][j][k][0]=f[s^1][i][j][k][0]+(lf[i][j-1]==lf[i][l])*f[s^1][i+1][j][k][1]+(i==X&&l==Y&&lf[i][j-1]==lf[i][l]);
f[s][i][j][k][1]=f[s^1][i][j][k-1][1]+(up[i-1][l]==up[k][l])*f[s^1][i][j][k][2]+(k==X&&l==Y&&up[i-1][l]==up[k][l]);
f[s][i][j][k][2]=f[s^1][i][j+1][k][2]+(lf[k][j-1]==lf[k][l])*f[s^1][i][j][k-1][3]+(k==X&&j==Y&&lf[k][j-1]==lf[k][l]);
f[s][i][j][k][3]=f[s^1][i+1][j][k][3]+(up[k][j]==up[i-1][j])*f[s^1][i][j+1][k][0]+(i==X&&j==Y&&up[i-1][j]==up[k][j]);
F(o,0,3) f[s][i][j][k][o]%=p;
}
}
}
}
printf("%d\n",f[s][1][1][n][3]);
return 0;
}