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 (x2−x1)2+(y2−y1)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,(1≤n,m≤1018,0≤r≤100), 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(1≤x≤n,1≤y≤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
 
思路:先找马可以走到的点,可以发现点均分布在斜率为-1的直线上,个数为1、2、3、4…… 所以可以把这些点对应到第一象限,这些点分别为(1,1)  (1,2)、(2,1)
(1,3)、(2,2)、(3,1)   (1,4)(2,3)、(3,2)、(4,1) 刚好充满第一象限,这时可以用组合数方便算出从某点到另一点的路径数,由于坐标很大,所以必须使用卢卡斯定理求组合数,注意去重,因为有障碍点。
 
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
const long long mod=;
typedef long long LL;
struct Node
{
long long x;
long long y;
long long s;
}node[]; int cmp(const Node s1,const Node s2)
{
if(s1.x==s2.x)
return s1.y<s2.y;
return s1.x<s2.x;
} LL PowMod(LL a,LL b,LL MOD)
{
LL ret=;
while(b)
{
if(b&) ret=(ret*a)%MOD;
a=(a*a)%MOD;
b>>=;
}
return ret;
} LL fac[]; LL Get_Fact(LL p)
{
fac[]=;
for(int i=; i<=p; i++)
fac[i]=(fac[i-]*i)%p;
} LL calc(LL n,LL m,LL p)
{
LL ret=;
while(n&&m)
{
LL a=n%p,b=m%p;
if(a<b) return ;
ret=(ret*fac[a]*PowMod(fac[b]*fac[a-b]%p,p-,p))%p;
n/=p;
m/=p;
}
return ret;
} int main()
{
long long n,m;
int r;
int Case=;
Get_Fact(mod);
while(scanf("%lld%lld%d",&n,&m,&r)!=EOF)
{
int tot=;
long long sum=;
int flag=;
if((n+m+)%==)
{
long long s=(n+m+)/;
if(n>=s&&m>=s)
{
long long t=n;
n=*s-m;
m=*s-t;
}
else
{
flag=;
}
}
else
{
flag=;
}
for(int i=;i<r;i++)
{
long long x,y;
scanf("%lld%lld",&x,&y);
if((x+y+)%==)
{
long long s=(x+y+)/;
if(x>=s&&y>=s)
{
node[tot].x=*s-y;
node[tot].y=*s-x;
if(node[tot].x<=n&&node[tot].y<=m)
tot++;
}
}
}
if(flag==)
{
printf("Case #%d: %lld\n",Case++,sum);
continue;
}
if(tot>)
sort(node,node+tot,cmp);
sum=calc(n+m-,n-,mod)%mod;
// cout<<"n: "<<n<<" m: "<<m<<endl;
//cout<<tot<<endl;
//cout<<sum<<endl;
//for(int i=0;i<tot;i++)
//cout<<"tot: "<<node[i].x<<" "<<node[i].y<<endl;
for(int i=;i<tot;i++)
{
node[i].s=calc(node[i].x+node[i].y-,node[i].x-,mod)%mod;
}
for(int i=;i<tot;i++)
{
long long tt=calc(n-node[i].x+m-node[i].y,m-node[i].y,mod);
for(int j=i+;j<tot;j++)
{
if(node[j].y>=node[i].y)
{
long long d1=node[j].y-node[i].y;
long long d2=node[j].x-node[i].x;
node[j].s=(node[j].s-(node[i].s*calc(d1+d2,d1,mod))%mod)%mod;
}
}
sum=(sum-(node[i].s*tt)%mod)%mod;
sum = (sum%mod+mod)%mod;
}
printf("Case #%d: %lld\n",Case++,sum);
}
}

2016暑假多校联合---A Simple Chess的更多相关文章

  1. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  2. 2016暑假多校联合---Windows 10

    2016暑假多校联合---Windows 10(HDU:5802) Problem Description Long long ago, there was an old monk living on ...

  3. 2016暑假多校联合---Substring(后缀数组)

    2016暑假多校联合---Substring Problem Description ?? is practicing his program skill, and now he is given a ...

  4. 2016暑假多校联合---To My Girlfriend

    2016暑假多校联合---To My Girlfriend Problem Description Dear Guo I never forget the moment I met with you. ...

  5. 2016暑假多校联合---Another Meaning

    2016暑假多校联合---Another Meaning Problem Description As is known to all, in many cases, a word has two m ...

  6. 2016暑假多校联合---Death Sequence(递推、前向星)

    原题链接 Problem Description You may heard of the Joseph Problem, the story comes from a Jewish historia ...

  7. 2016暑假多校联合---Counting Intersections

    原题链接 Problem Description Given some segments which are paralleled to the coordinate axis. You need t ...

  8. 2016暑假多校联合---Joint Stacks (STL)

    HDU  5818 Problem Description A stack is a data structure in which all insertions and deletions of e ...

  9. 2016暑假多校联合---GCD

    Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). ...

随机推荐

  1. JavaScript模板引擎实例应用

    在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及如何使用,文末还提到了laytpl.art ...

  2. Atitit hsv转grb  应该优先使用hsv颜色原则 方便人类

    Atitit hsv转grb  应该优先使用hsv颜色原则 方便人类 1.1. 1.1.hsv色卡1 1.2. 从 HSV 到 RGB 的转换1 1.3. HSVtoRGBColorV22 1.1.  ...

  3. flow.ci + Github + Slack 一步步搭建 Python 自动化持续集成

    理想的程序员必须懒惰,永远追随自动化法则.Automating shapes smarter future. 在一个 Python 项目的开发过程中可能会做的事情:编译.手动或自动化测试.部署环境配置 ...

  4. jQuery对 动态添加 的元素 绑定事件(on()的用法)

    从jQuery 版本 1.7 起,on() 方法是向被选元素添加事件处理程序的(官方推荐)首选方法. 当浏览器下载完一个页面的时候就开始渲染(翻译)HTML标签,然后执行css.js代码,在执行js代 ...

  5. Android 4.2版本以下使用WebView组件addJavascriptInterface方法存在JS漏洞

    JS注入漏洞存在的Android版本:Android < 4.2 综述:Android的SDK中提供了一个WebView组件,用于在应用中嵌入一个浏览器来进行网页浏览.WebView组件中的ad ...

  6. react5 事件 satate

    <body><!-- React 真实 DOM 将会插入到这里 --><div id="example"></div> <!- ...

  7. BrowserSync前端调试工具使用

    上次介绍了一款DebugGap移动端调试工具DebugGap推荐.但是这几天使用了之后感觉还是有些不足,尤其是里面的调试工具虽然和Chrome里面的调试长的很像,但是多少有些不同,使用起来还是不太方便 ...

  8. 30分钟全面解析-图解AJAX原理

    先上原理图: 高清无码图在这里:点我查看大图!!! 背景: 1.传统的Web网站,提交表单,需要重新加载整个页面. 2.如果服务器长时间未能返回Response,则客户端将会无响应,用户体验很差. 3 ...

  9. Sort the Array

    /* 思路: 找到单调下降串的起始位置[l, r] 如果左边 0...l-1中的最大值 > l...r中的最小值 或者 r+1...n中的最小值 < l...r中的最大值 都是不能实现排序 ...

  10. Ruby FFI 入门教程

    FFI是一个可以让用户使用Ruby调用C代码的gem.如果你需要执行一些系统底层调用,或者做一些高性能运算的话,FFI是一个很不错的选择. 1. 安装 执行gem install ffi即可.非常标准 ...