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

    题目:A Simple Chess

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5794

    题意:起始点(1,1),要到达(n,m),下一步(x2,y2),这一步(x1,y1),需满足(x2-x1)^2 +(y2-y1)^2 = 5,且 x2>x1 、y2>y1。中间还有r 个障碍点,问最终有多少种方法到达(n,m)。n、m高达10^18,r最多100。

    思路:

      

      大概画一下图,就可以知道从(1,1)到(n,m)的方法数是一个组合数。

      现在问题是障碍点,我们可以先计算(1,1)到每个障碍点的方法数sum(先当做这个障碍点不受其他障碍点影响),然后对障碍点排序,排序方法是从内圈到外圈( 其实可到达的点会形成无数的同心圆 ),然后两重循环,判断这个障碍点p1会对哪些障碍点(和终点)p2照成影响,受影响的障碍点sum减去影响数(p1.sum*组合数(这个组合数是从p1到p2的方法数)),逐层排查。就可以计算出(n,m)还剩下多少种方法可到达。

      难点就在于大组合数取模了...我事先也没有准备模板,临时盗用别人的。。

    AC代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 using namespace std;
      5 #define N 150000
      6 typedef long long LL;
      7 struct Node
      8 {
      9   LL x,y,sum;
     10   bool friend operator < (Node a,Node b)
     11   {
     12     return a.x+a.y<b.x+b.y;
     13   }
     14 };
     15 const LL p=110119;
     16 LL fac[N];
     17 void init()
     18 {
     19     int i;
     20     fac[0] =1;
     21     for(i =1; i <= p; i++)
     22         fac[i] = fac[i-1]*i%p;
     23 }
     24 LL pow(LL a, LL b)
     25 {
     26     LL tmp = a % p, ans =1;
     27     while(b)
     28     {
     29         if(b &1)  ans = ans * tmp % p;
     30         tmp = tmp*tmp % p;
     31         b >>=1;
     32     }
     33     return  ans;
     34 }
     35 LL C(LL n, LL m)
     36 {
     37     if(m>n)return 0;
     38     return  fac[n]*pow(fac[m]*fac[n-m],p-2)%p;
     39 }
     40 LL cfun(LL n, LL m)
     41 {
     42     if(m ==0)  return 1;
     43     else return  (C(n%p,m%p)*cfun(n/p, m/p))%p;
     44 }
     45 Node a[110];
     46 int ao;
     47 
     48 bool check(Node a,Node b)
     49 {
     50   if( (b.x+b.y-a.x-a.y) % 3 != 0 ) return false;
     51   LL t=b.y-a.y;
     52   if(b.x-a.x<=2*t && 2*(b.x-a.x) >=t ) return true;
     53   return false;
     54 }
     55 LL solve(Node a,Node b)
     56 {
     57   if(b.x==a.x && b.y==a.y) return a.sum;
     58   if( !check(a,b) ) return 0;
     59   LL xia=(b.x+b.y-a.x-a.y)/3;
     60   LL shang=(b.y-a.y)-xia;
     61   return (a.sum*cfun(xia,shang))%p;
     62 }
     63 
     64 int main()
     65 {
     66   init();
     67   LL n,m;
     68   int r,cas=1;
     69   while(scanf("%I64d%I64d%d",&n,&m,&r)!=EOF)
     70   {
     71     Node s,t;
     72     s.sum=1;
     73     s.x=0,s.y=0;
     74     n--,m--;
     75     t.x=n,t.y=m;
     76     t.sum=solve(s,t);
     77     ao=0;
     78     for(int i=0;i<r;i++)
     79     {
     80       scanf("%I64d%I64d",&a[ao].x,&a[ao].y);
     81       a[ao].x--,a[ao].y--;
     82       if( !check(s,a[ao]) ) continue;
     83       ao++;
     84     }
     85     for(int i=0;i<ao;i++)
     86     {
     87       a[i].sum=solve(s,a[i]);
     88     }
     89     sort(a,a+ao);
     90     for(int i=0;i<ao;i++)
     91     {
     92       for(int j=i+1;j<ao;j++)
     93       {
     94         if( check(a[i],a[j]) )
     95         {
     96           a[j].sum=(a[j].sum-solve(a[i],a[j])+p)%p;
     97         }
     98       }
     99       t.sum=(t.sum-solve(a[i],t)+p)%p;
    100     }
    101     printf("Case #%d: ",cas++);
    102     printf("%I64d
    ",t.sum);
    103   }
    104   return 0;
    105 }
  • 相关阅读:
    《一起》个人进展——Day05
    《一起》个人进展——Day04
    《一起》个人进展——Day03
    《一起》个人进展——Day02
    《一起》个人进展——Day01
    this
    java_流
    input _文本框回车或者失去光标触发事件
    removeAll
    SysLog简介和java操作实例
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/5740838.html
Copyright © 2011-2022 走看看