zoukankan      html  css  js  c++  java
  • HDU-5794 A Simple Chess

    题目描述

    棋子在(n*m)棋盘上可以走马步(横走(1)竖走(2)或横走(2)竖走(1)

    只能往格子坐标增大的方向跳,且棋盘中会有一些障碍物

    问棋子从((1,1))走到((n,m))有几种方案mod((110119))

    Input

    输入包含多组数据

    第一行三个整数(n,m,r,(1<=n,m<=1e18,0<=r<=100),)

    接下来(r)行,每行两个整数(x,y,(1<=x<=n,1<=y<=m),)

    表示障碍物位置((1,1))上不会有障碍物

    Output

    对于每组测试数据,输出一行"Case #x: y",x是组数,y是答案

    Sample Input

    1 1 0
    3 3 0
    4 4 1
    2 1
    4 4 1
    3 2
    7 10 2
    1 2
    7 1
    

    Sample Output

    Case #1: 1
    Case #2: 0
    Case #3: 2
    Case #4: 1
    Case #5: 5
    

    ​ 容斥(dp)+(lucas)定理。

    题目要我们求出不碰到任意障碍物的方案数,直接求这个方案数是十分麻烦的。

    我们可以转换成从起点出发到第(i)个障碍物不碰到任意障碍物的方案数。

    我们先把在((n,m))处放置一个障碍物,再把所有的障碍物按照(x)排序。

    我们定义(dp[i])表示从起点出发到第(i)个障碍物不碰到任意障碍物的方案数。

    (calc[x1,y1,x2,y2])表示从(x1,y1)到第(x2,y2)个障碍物的方案数。

    排序好之后,我们对于第(i)个障碍物:

    (dp[i]=calc[1,1,x_i,y_i]-sum calc(x_j,y_j,x_i,y_i)*dp[j],(j=起点到第i的路径上的障碍))

    现在我们就是要求出(calc(x1,y1,x2,y2))


    首先设(X=x2-x1,Y=y2-y1),横走(1)竖走(2)走了(a)步,或横走(2)竖走(1)走了(b)步。

    所以我们有(a+2*b=X)(b+2*a=Y)

    我们可以解出(a,b),若(a,b)​无整数解则无法从((x1,y1))((x2,y2))

    解出了(a,b)后答案就是(C(a+b,a))了。

    只是(a,b)比较大,而我们发现模数(110119)是一个质数。

    所以我们可以利用(lucas)定理。


    (lucas)定理:当(p)为质数时,(C(a,b)\%p=C(a/p,b/p)*C(a\%p,b\%p)\%p)

    代码如下

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    
    #define int long long
    #define reg register
    #define Raed Read
    #define clr(a,b) memset(a,b,sizeof a)
    #define Mod(x) (x>=mod)&&(x-=mod)
    #define debug(x) cerr<<#x<<" = "<<x<<endl;
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)>(b)?(b):(a))
    #define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
    #define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
    #define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
    #define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
    #pragma GCC target("avx,avx2,sse4.2")
    #pragma GCC optimize(3)
    
    inline int Read(void) {
    	int res=0,f=1;
    	char c;
    	while(c=getchar(),c<48||c>57)if(c=='-')f=0;
    	do res=(res<<3)+(res<<1)+(c^48);
    	while(c=getchar(),c>=48&&c<=57);
    	return f?res:-res;
    }
    
    template<class T>inline bool Min(T &a, T const&b) {
    	return a>b?a=b,1:0;
    }
    template<class T>inline bool Max(T &a, T const&b) {
    	return a<b?a=b,1:0;
    }
    
    const int N=105,M=1e5+5,mod=110119;
    
    bool MOP1;
    
    struct node {
    	int x,y;
    	bool operator<(node _)const {
    		if(x==_.x)return y<_.y;
    		return x<_.x;
    	}
    } A[N];
    
    int dp[N];
    
    bool MOP2;
    
    int Fac[mod+5],Inv[mod+5],V[mod+5];
    
    int C(int a,int b) {
    	if(a<b||b<0)return 0;
    	if(a<mod&&b<mod)return 1ll*Fac[a]*((1ll*Inv[a-b]*Inv[b])%mod)%mod;
    	return (1ll*C(a%mod,b%mod)*C(a/mod,b/mod)%mod)%mod;
    }
    
    inline int calc(int x,int y) {
    	int tot=x+y;
    	if(tot%3)return 0;
    	int a=x-tot/3,b=y-tot/3;
    	return C(a+b,a);
    }
    
    inline void _main(void) {
    	int Case=0,n,m,k;
    	Fac[0]=Inv[0]=Fac[1]=V[1]=Inv[1]=1ll;
    	ret(i,2,mod) {
    		Fac[i]=(1ll*Fac[i-1]*i)%mod;
    		V[i]=1ll*(mod-mod/i)*V[mod%i]%mod;
    		Inv[i]=(1ll*Inv[i-1]*V[i])%mod;
    	}
    	while(~scanf("%lld %lld %lld",&n,&m,&k)) {
    		int f=0;
    		rep(i,1,k) {
    			A[i]=(node)<%Read(),Read()%>;
    			if(A[i].x==n&&A[i].y==m)f=1;
    		}
    		A[++k]=(node)<%n,m%>,sort(A+1,A+k+1);
    		clr(dp,0);
    		rep(i,1,k) {
    			dp[i]=calc(A[i].x-1,A[i].y-1);
    			ret(j,1,i)if(A[j].y<=A[i].y) {
    				int res=(dp[j]*calc(A[i].x-A[j].x,A[i].y-A[j].y))%mod;
    				dp[i]=((dp[i]-res)%mod+mod)%mod;
    			}
    		}
    		printf("Case #%lld: %lld
    ",++Case,dp[k]);
    	}
    
    }
    
    signed main() {
    	_main();
    	return 0;
    }
    
  • 相关阅读:
    mysql cpu 占用高
    使用cron命令配置定时任务(cron jobs)
    python 获取时间
    linux 免密码登陆
    linux 查看登录日志
    shizhong
    正则(?is)
    python shell
    linux 时间设置
    java获取当前时间前一周、前一月、前一年的时间
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11429903.html
Copyright © 2011-2022 走看看