原题链接:路径计数 - 题目 - Daimayuan Online Judge
解题思路:本题是路径计数2的弱化版,思路与其完全一致。详细思路见路径计数2的博客。
[海豹海边爆]Daimayuan467_haruka_rue的博客-CSDN博客
唯一需要修改的就是输入数据的处理过程。当读到0的时候计入不可通行点即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
long long fact[10000010],inv[10000010];//fact存阶乘,inv存对应逆元
long long n,m,sum[1000010];//sum为到达不同点的不重复路径数
struct qwq{//存点
long long x,y;
} p[1000010];
long long int_pow(long long x,long long k){//快速幂
long long ans=1 ;
while(k){
if(k&1) ans=ans*x%mod;
k=k>>1;
x=(x*x)%mod;
}
return ans ;
}
void pre_work(){//预处理阶乘与逆元
fact[0]=1;
fact[1]=1;
for(long long i=2;i<=10000000;i++) fact[i]=fact[i-1]*i,fact[i]%=mod;
inv[10000000]=int_pow(fact[10000000],mod-2);
for(long long i=9999999;i>0;i--) inv[i]=inv[i+1]*(i+1)%mod;
inv[0]=1;
return;
}
int cmp(qwq a,qwq b) {//sort排序的判断函数
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int main(){
pre_work();
cin>>n;//输入
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int buffer;
cin>>buffer;//输入图
if(!buffer){//点为0即不可通行点
p[js].x=i;
p[js].y=j;
js++;
}
}
}
p[js].x=n;//终点也一样处理
p[js].y=n;
m=js+1;
sort(p,p+m,cmp);//排序
long long x1,y1,x2,y2;//缓存数据,防止重复计算
for(int i=0;i<m;i++){//遍历每个不可通行点
x1=p[i].x-1;
y1= p[i].y-1;
sum[i]=fact[x1+y1]*inv[x1]%mod*inv[y1]%mod;//组合数公式计算没有其他点干扰的路径数
for(int j=0;j<i;j++) {//查是否有重复路径
if(p[j].x<=p[i].x&&p[j].y<=p[i].y) {//如果有则减去通过那些点的路径
x2=x1-p[j].x+1;
y2=y1-p[j].y+1;
sum[i]=(sum[i]-fact[x2+y2]*inv[x2]%mod*inv[y2]%mod*sum[j]%mod)%mod;
if(sum[i]<=0) sum[i]=(sum[i]+mod)%mod;
}
}
}
cout<<sum[m-1];
return 0;
}