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
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议
    OCM_第十三天课程:Section6 —》数据库性能调优 _结果缓存 /多列数据信息采集统计/采集数据信息保持游标有效
    OCM_第十二天课程:Section6 —》数据库性能调优_ 资源管理器/执行计划
    使用NuGet时的一个乌龙
    .net调用存储过程碰到的一个问题
    数据库的备份与还原
    创建link server链接服务器碰到的问题及解决办法
    如何管理好项目的DLL
    项目中Enum枚举的使用
    .NET开发知识体系
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14931534.html
Copyright © 2011-2022 走看看