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

    A Simple Chess

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 614    Accepted Submission(s): 159


    Problem 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 (x2,y2) from the position (x1,y1), only and if only x1,y1,x2,y2 is satisfied that (x2x1)2+(y2y1)2=5, x2>x1, y2>y1.
    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,(1n,m1018,0r100), 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(1xn,1ym), 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
     
    如果一共有x个障碍点:
    设dp[i]为到达第i个障碍点且不经过他之前的障碍点的方法数,那么我们把终点(n,m)加进去,dp[x+1]就是我们要求的答案。
     
    状态方程 dp[i]=C(x[i]+y[i],x[i])-sum(dp[j]*C(x[i]-x[j]+y[i]-y[j],x[i]-x[j]));
     
    可以写个方法 cal  用来计算上一个点到达这个点的方法数,如果不可达,直接就是0否则是C(x,y)类型的。
     
    /* ***********************************************
    Author        :guanjun
    Created Time  :2016/8/4 19:31:58
    File Name     :hdu5794.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define MOD 110119
    #define INF 0x3f3f3f3f
    #define maxn 110119
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct node{
        ll x,y;
    }p[1000];
    ll dp[1000],inv[maxn],fac[maxn];
    bool cmp(node a,node b){
        if(a.x==b.x)
            return a.y<b.y;
        return a.x<b.x;
    }
    ll Pow(ll a,ll n,ll m){
        ll ans=1;
        while(n){
            if(n&1) {
                ans*=a;
                ans%=m;
            }
            a=a*a%m;
            n>>=1;
        }
        return ans;
    }
    ll C(ll n,ll m,ll p){
        ll res=1;
        while(n&&m){
            ll a=n%p;
            ll b=m%p;
            if(a<b)return 0;
            res=res*fac[a]%p*Pow(fac[b]*fac[a-b]%p,p-2,p)%p;
            n/=p;
            m/=p;
        }
        return res;
    }
    void init(){
        fac[0]=1;
        inv[0]=1;
        for(int i=1;i<=maxn;i++){
            fac[i]=fac[i-1]*i%MOD;
            inv[i]=Pow(fac[i],MOD-2,MOD);
        }
    }
    ll cal(node a,node b){
        ll dx=b.x-a.x;
        ll dy=b.y-a.y;
        ll x,y;
        if((dx+dy)%(ll)3!=0)return 0;
        x=(2*dx-dy)/3;
        y=(2*dy-dx)/3;
        if(x<0||y<0)return 0;
        if(x==0||y==0)return 1;
        return C(x+y,x,MOD);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        init();
        ll h,w;
        int n,cas=0;
        while(~scanf("%I64d %I64d %d",&h,&w,&n)){
            cle(dp);
            for(int i=1;i<=n;i++)scanf("%I64d %I64d",&p[i].x,&p[i].y);
            p[0].x=1LL,p[0].y=1LL;
            p[++n].x=h;p[n].y=w;
            sort(p+1,p+1+n,cmp);
            for(int i=1;i<=n;i++){
                dp[i]=cal(p[0],p[i]);
                for(int j=1;j<i;j++)
                    if(p[j].x<=p[i].x&&p[j].y<=p[i].y)
                        dp[i]=((dp[i]-cal(p[j],p[i])*dp[j]%MOD)%MOD+MOD)%MOD;
            }
            printf("Case #%d: %I64d
    ",++cas,dp[n]);
        }
        return 0;
    }
  • 相关阅读:
    win10下以管理员身份打开hosts文件
    使用Dockerfile构建镜像命令自己的理解
    我们在删除镜像的时候被告知有容器正在使用,可是容器已经被停止了
    Docker构建镜像过于缓慢解决-----Docker构建服务之部署和备份jekyll网站
    VMware虚拟机ubuntu显示屏幕太小解决办法
    树莓派3B从装系统到安装RYU过程
    树莓派3b 换国内源 更新源
    Raspbain系统无屏幕无网线通过ssh远程连接树莓派设置wifi步骤
    Mplayer 隐藏边框和显示位置的方法
    使用mplayer查看摄像头
  • 原文地址:https://www.cnblogs.com/pk28/p/5740214.html
Copyright © 2011-2022 走看看