zoukankan      html  css  js  c++  java
  • [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
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    Python之Pyautogui模块20180125《PYTHON快速上手让繁琐的工作自动化》18章
    〈Android 群英传-神兵利器〉第7章一个的寂寞与一群人的狂欢
    一,Android Studio笔记
    一、探索 Android Studio
    微服务之网关:Ocelot+Consul实现动态集群扩展
    MacOS任意降级
    微服务之注册服务与发现:Consul在Windows下安装使用
    .Net Core中使用 AutoMapper
    .Net Core中使用Swagger
    .NetCore中使用EF Core
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14931534.html
Copyright © 2011-2022 走看看