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. Atitit  深入理解命名空间namespace  java c# php js

    Atitit  深入理解命名空间namespace  java c# php js 1.1. Namespace还是package1 1.2. import同时解决了令人头疼的include1 1.3 ...

  2. python学习 文件操作

    一.python打开文件 #=====================python 文件打开方式 open()===================== # open(fileName,type) t ...

  3. 如何优雅的使用vue+vux开发app -01

    如何优雅的使用vue+vux开发app -01 很明显下面是个错误的示范: <!DOCTYPE html> <html> <head> <title>v ...

  4. Python下划线与命名规范

    Python下划线与命名规范 先看结论,节省只想知道答案你的宝贵时间: _xxx 不能用于from module import * 以单下划线开头的表示的是protected类型的变量.即保护类型只能 ...

  5. js阻止冒泡及jquery阻止事件冒泡示例介绍

    js阻止冒泡 在阻止冒泡的过程中,W3C和IE采用的不同的方法,那么我们必须做以下兼容. 复制代码 代码如下: function stopPro(evt){ var e = evt || window ...

  6. CSS选择器的浏览器支持

    CSS1 CSS2 CSS 3 :hover 在IE6中只有a元素可用. E:empty 貌似在webkit核心浏览器中有些小bug. 如果这个bug依然存在,不太确定如何测试. IE6不支持.cla ...

  7. 深入理解CSS浮动

    × 目录 [1]定义 [2]特性 [3]表现 [4]重叠 前面的话 浮动最早的使用是出自<img src="#" align="right">,用于 ...

  8. 使用余弦定理制作磁盘形状h5音乐播放器

    目录 [1]功能实现 [2]效果展示 [3]原理说明 旋转原理 余弦定理 [4]代码实现 HTML CSS JS [5]源码查看 功能实现 [1]歌曲播放进度转换成视觉的旋转角度 [2]点击磁盘任意位 ...

  9. 《BI那点儿事》Microsoft 决策树算法——找出三国武将特性分布,献给广大的三国爱好者们

    根据游戏<三国志11>武将数据,利用决策树分析,找出三国武将特性分布.其中变量包括统率.武力.智力.政治.魅力.身分.变量说明:统率:武将带兵出征时的部队防御力.统帅越高受到普通攻击与兵法 ...

  10. .Net Request.Form含有危险字符的处理办法

    今天我们的网站遇到一个问题,下标就类似于化学分子式这样的是需要用"<sub></sub>"这个标签括起来的,当时没有转义,有部分标签就显示不出来了, 后来我 ...