题目链接
可以挡住起点旁两个格子,故答案最多为
222
2 22
222。若
(
1
,
1
)
(1,1)
(1,1)到不了
(
n
,
m
)
(n,m)
(n,m),则答案为0。否则记
F
1
[
x
]
[
y
]
F1[x][y]
F1[x][y]为
(
1
,
1
)
(1,1)
(1,1)到
(
x
,
y
)
(x,y)
(x,y)的路径数,
F
2
[
x
]
[
y
]
F2[x][y]
F2[x][y]为
(
x
,
y
)
(x,y)
(x,y)到
(
n
,
m
)
(n,m)
(n,m)的路径数。如果有一个
(
x
,
y
)
(x,y)
(x,y)满足
F
1
[
x
]
[
y
]
∗
F
2
[
x
]
[
y
]
=
F
1
[
n
]
[
m
]
F 1 [ x ] [ y ] ∗ F 2 [ x ] [ y ] = F 1 [ n ] [ m ]
F1[x][y]∗F2[x][y]=F1[n][m],则
(
x
,
y
)
(x,y)
(x,y)是必经点,挡住它即可,答案为1;否则答案为2。写个DP取一个较大的模数即可。
该题直接用map会超时,所以要将二维转换成一维的形式
#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
typedef unsigned long long ULL;
typedef pair<double,double> PDD;
typedef long long LL;
typedef pair<LL,LL> PII;
#define int LL
//#define int ULL
//#define x first
#define y second
const int inf=0x3f3f3f3f;
//const int mod=1e9+9;
const int mod=998244353;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=(s<<1)+(s<<3)+(ch-'0');
ch=getchar();
}
return s*w;
}
const int maxn=2e6+5;
int n,m;
char maps[maxn];
int f[maxn],g[maxn];
bool flag[maxn];
int get(int x,int y){
return (x-1)*m+y;
}
bool dfs(int x,int y){
if(x==0||x==n+1||y==0||y==m+1) return false;
if(maps[get(x,y)]=='#') return false;
if(flag[get(x,y)]) return false;
if(x==n&&y==m) return true;
flag[get(x,y)]=true;
bool is_flag=false;
is_flag|=dfs(x+1,y);
is_flag|=dfs(x,y+1);
return is_flag;
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>maps[get(i,j)];
if(!dfs(1,1)){
cout<<0<<'\n';
return ;
}
f[1]=g[n*m]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(maps[get(i,j)]=='#') continue;
if(i==1&&j==1) continue;
f[get(i,j)]=(f[get(i-1,j)]+f[get(i,j-1)])%mod;
}
for(int i=n;i>=1;i--)
for(int j=m;j>=1;j--){
if(i==n&&j==m) continue;
if(maps[get(i,j)]=='#') continue;
g[get(i,j)]=(g[get(i+1,j)]+g[get(i,j+1)])%mod;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1&&j==1) continue;
if(i==n&&j==m) continue;
if((f[get(i,j)]*g[get(i,j)])%mod==f[get(n,m)]){
cout<<1<<'\n';
return ;
}
}
}
cout<<2<<'\n';
}
signed main(){
ios;
int t;t=1;
while(t--) solve();
return 0;
}