• [HDU5794]A Simple Chess


    Description
    There is a (n×m) board, a chess want to go to the position ((n,m)) from the position ((1,1)).
    The chess is able to go to position ((x_2,y_2)) from the position ((x_1,y_1)), only and if only (x_1,y_1,x_2,y_2) is satisfied that ((x_2−x_1)^2+(y_2−y_1)^2=5, x_2>x_1, y_2>y_1).
    Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle.
    I want you to tell me, There are how may ways the chess can achieve its goal.

    Input
    The input consists of multiple test cases.
    For each test case:
    The first line is three integers, (n,m,r,(1leqslant n,mleqslant 10^{18},0leqslant rleqslant100)), denoting the height of the board, the weight of the board, and the number of the obstacles on the board.
    Then follow (r) lines, each lines have two integers, (x,y(1leqslant xleqslant n,1leqslant yleqslant m)), denoting the position of the obstacles. please note there aren't never a obstacles at position ((1,1)).

    Output
    For each test case,output a single line "Case #x: y", where x is the case number, starting from 1. And y is the answer after module 110119.

    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
    

    尽管本题是走日字,但由于每次必须向坐标更大的地方跳,故实际上和普通的走法无较大区别,需要注意的一点是要判断一个点是否能通过跳日字到达另一个点

    对于障碍点的计算,记(A)到终点的所有路径数为(S_A),记(T_A)(A)出发不经过任何障碍点到达终点的路径数,则有(T_A=S_A-sumlimits_{A<B}T_B),其中(B)为障碍点,(A<B)表示(A)的坐标严格小于(B),即(A)可以通过某些方式跳到(B)

    我们将起点(O)也加入障碍点,最后算出的(T_O)即为答案

    注意在计算的时候,组合数会非常大,因此需要用到Lucas定理:(inom{n}{m}equivinom{n\%p}{m\%p}inom{n/p}{m/p} \% p)

    /*program from Wolfycz*/
    #include<map>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define Fi first
    #define Se second
    #define ll_inf 1e18
    #define MK make_pair
    #define sqr(x) ((x)*(x))
    #define pii pair<int,int>
    #define int_inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    template<typename T>inline T frd(T x){
    	int f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    template<typename T>inline T read(T x){
    	int f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e3,P=110119;
    struct node{
    	ll x,y;
    	node(ll _x=0,ll _y=0){x=_x,y=_y;}
    	void clear(){x=y=0;}
    	void insert(ll _x,ll _y){x=_x,y=_y;}
    	void print(){printf("%lld %lld
    ",x,y);}
    	bool operator <(const node &tis)const{return x!=tis.x?x<tis.x:y<tis.y;}
    	bool operator ==(const node &tis)const{return x==tis.x&&y==tis.y;}
    }Obstacles[N+10];
    int fac[P+10],inv[P+10];
    int C(ll n,ll m){
    	if (n<m)	return 0;
    	if (n<P&&m<P)	return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;
    	return 1ll*C(n/P,m/P)*C(n%P,m%P)%P;
    }
    void prepare(){
    	fac[0]=inv[0]=inv[1]=1;
    	for (int i=1;i<P;i++)	fac[i]=1ll*i*fac[i-1]%P;
    	for (int i=2;i<P;i++)	inv[i]=1ll*(P-P/i)*inv[P%i]%P;
    	for (int i=1;i<P;i++)	inv[i]=1ll*inv[i-1]*inv[i]%P;
    }
    int solve(ll x,ll y){
    	ll delta=abs(x-y),cnt=(min(x,y)-delta)/3;
    	return C((cnt<<1)+delta,cnt);
    }
    bool Check(ll x,ll y){
    	ll delta=abs(x-y);
    	if (min(x,y)<delta)	return 0;
    	if ((min(x,y)-delta)%3)	return 0;
    	return 1;
    }
    int Ans[N+10];
    void init(){
    	memset(Ans,0,sizeof(Ans));
    	for (int i=0;i<=N;i++)	Obstacles[i].clear();
    }
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	prepare();
    	ll n,m; int r,Case=0;
    	while (scanf("%lld%lld%d",&n,&m,&r)!=EOF){
    		int cnt=0; bool Flag=0;
    		n--,m--; init();
    		for (int i=1;i<=r;i++){
    			ll x=read(0ll)-1,y=read(0ll)-1;
    			if (x==n&&y==m)	Flag|=1;
    			if (!Check(x,y))	continue;
    			Obstacles[++cnt].insert(x,y);
    		}
    		Obstacles[++cnt].insert(n,m);
    		if (!Check(n,m)||Flag){
    			printf("Case #%d: 0
    ",++Case);
    			continue;
    		}
    		sort(Obstacles+1,Obstacles+1+cnt);
    		for (int i=1;i<=cnt;i++){
    			Ans[i]=solve(Obstacles[i].x,Obstacles[i].y);
    			for (int j=1;j<i;j++){
    				if (Obstacles[j]<Obstacles[i]){
    					ll X_i=Obstacles[i].x,Y_i=Obstacles[i].y;
    					ll X_j=Obstacles[j].x,Y_j=Obstacles[j].y;
    					if (!Check(X_i-X_j,Y_i-Y_j))	continue;
    					Ans[i]=(Ans[i]-1ll*Ans[j]*solve(X_i-X_j,Y_i-Y_j)%P)%P;
    				}else	break;
    			}
    			Ans[i]=(Ans[i]+P)%P;
    		}
    		printf("Case #%d: %d
    ",++Case,Ans[cnt]);
    	}
    	return 0;
    }
    
    作者:Wolfycz
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    结对作业
    读《构建之法》第四章、第十七章
    2016012060+小学四则运算练习软件项目报告
    《构建之法》第1、2、16章阅读随笔
    我与软件
    2016012039+张琪+散列函数的应用及其安全性
    结对作业
    读《构建之法》第四、十七章有感
    2016012039 + 小学四则运算练习软件项目报告
    读书笔记(第1、2、16章)
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14931534.html
Copyright © 2020-2023  润新知