D. Treasure Island(dp+双模数)

首 先 是 数 据 范 围 , 只 能 开 一 维 数 组 模 拟 二 维 数 组 首先是数据范围,只能开一维数组模拟二维数组 ,

然 后 答 案 最 坏 是 2 , 因 为 可 以 在 起 点 两 边 堵 住 然后答案最坏是2,因为可以在起点两边堵住 2,

若 不 能 从 ( 1 , 1 ) 到 ( n , m ) 答 案 是 0 若不能从(1,1)到(n,m)答案是0 (1,1)(n,m)0

否 则 答 案 为 1 的 情 况 就 是 存 在 某 个 点 使 得 是 ( 1 , 1 ) 到 ( n , m ) 的 必 经 之 路 否则答案为1的情况就是存在某个点使得是(1,1)到(n,m)的必经之路 1使(1,1)(n,m)

考 虑 d p 考虑dp dp

d p [ i ] [ j ] 表 示 从 ( 1 , 1 ) 到 ( i , j ) 的 方 案 , f [ i ] [ j ] 表 示 从 ( n , m ) 到 ( i , j ) 的 方 案 dp[i][j]表示从(1,1)到(i,j)的方案,f[i][j]表示从(n,m)到(i,j)的方案 dp[i][j](1,1)(i,j),f[i][j](n,m)(i,j)

由 于 ( 1 , 1 ) 到 ( n , m ) 的 方 案 有 d p [ n ] [ m ] 种 由于(1,1)到(n,m)的方案有dp[n][m]种 (1,1)(n,m)dp[n][m]

而 经 过 点 ( i , j ) 的 路 径 有 d p [ i ] [ j ] ∗ f [ i ] [ j ] 种 而经过点(i,j)的路径有dp[i][j]*f[i][j]种 (i,j)dp[i][j]f[i][j]

那 么 比 较 是 否 相 等 即 可 那么比较是否相等即可

但 是 注 意 取 模 , 必 须 用 双 模 数 ( 我 第 一 次 双 模 数 都 被 卡 了 , 质 数 选 择 很 关 键 ) 但是注意取模,必须用双模数(我第一次双模数都被卡了,质数选择很关键) ,(,)

尽量选不常用的质数

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1000005;
const int mmod=1e9+333+7;
int n,m,dp[1000009],f[1000009],ddp[1000009],ff[1000009];
char a[1000009];
signed main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++) 
		cin >> a[(i-1)*m+j];
	dp[n*m]=1,ddp[n*m]=1;
	for(int i=n;i>=1;i--)
	for(int j=m;j>=1;j--)
	{
		if( i==n&&j==m )	continue;
		int now=(i-1)*m+j;
		int l=i*m+j,r=(i-1)*m+j+1;
		if( a[now]=='#' )	continue;
		if( j!=m )	dp[now]+=dp[r],ddp[now]+=ddp[r];
		if( i!=n )	dp[now]+=dp[l],ddp[now]+=ddp[l];
		dp[now]%=mod,ddp[now]%=mmod;
	}
	f[1]=1; ff[1]=1;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		if( i==1&&j==1 )	continue;
		int now=(i-1)*m+j;
		int l=(i-2)*m+j,r=(i-1)*m+j-1;
		if( a[now]=='#' )	continue;
		if( j!=1 )	f[now]+=f[r],ff[now]+=ff[r];
		if( i!=1 )	f[now]+=f[l],ff[now]+=ff[l];
		f[now]%=mod,ff[now]%=mmod; 		
	}
	if( f[n*m]==0&&ff[n*m]==0 )//一开始就到不了啊 
	{
		cout << 0;
		return 0;
	}
	int flag=0;
	for(int i=2;i<=n*m-1;i++)
		if( (dp[i]*f[i]%mod==dp[1] )&&(ddp[i]*ff[i]%mmod==ddp[1]) )	flag=1;//是必经之路
	if( flag )	cout << 1;
	else	cout << 2; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值