A Simple Chess

题目链接:

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

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

Source


2016 Multi-University Training Contest 6


##题意:

在n*m的棋盘上,从左上角(1,1)走到右下角(n,m)有多少条路线.
每次只能向右下方走"L"型路线. (x,y) => (x+1,y+2) or (x+2, y+1);
棋盘上有n个(n

##题解:

问题一:如何计算路线数
如果不存在任何障碍,从点(x1,y1)到点(x2,y2):
①. 不能到达:由于走的是"L"型路线(类似象棋的马),所以有可能到不了.
每走一步实际上是移动了三个单位(包括上下方向),而起点到终点共有(x2-x1) + (y2-y1)个单位.
所以能走到的充分必要条件是:((x2-x1)+(y2-y1)) % 3 == 0 ; 且终点在起点的左下方(x2>x1 && y2>y1).
②. 如果能到达:走的步数是 step = (x2+y2-x1-y1) / 3.
走法有 "L"型{(x,y)=>(x+2,y+1)} 和 "倒L"型{(x,y)=>(x+1,y+2)} 两种.
无论怎么走都至少会在上下两方向上都减1. 所以上下两方向各剩下 s1=x2-x1-step 和 s2=y2-y1-step 个单位.
再用"L"型和"倒L"型去分配这剩下的单位. 即 C(s1+s2, s1) 或 C(s1+s2, s2).
(另解:先看成往右下走一格,再抉择往右还是往下.)
③. 由于坐标范围较大,而取模的p=110119较小且为质数.
所以这里用lucas公式来求组合数.
(一般的:数较小且mod较大时用逆元求组合数,数较大且mod较小时用lucas求组合数)
(由于上述公式中s1 s2有可能为负数,所以lucas里面一定要对负数组合数作特判) (论完美模版的重要性).

问题二:如何考虑障碍物
容斥 + DP:坐标范围较大,只能对障碍位置进行dp:
dp[i]: 从(1,1)到障碍i且不经过其他障碍的路线数.
转移方程:
dp[i] = (起点到障碍i的路线) - Σ(dp[j] * (障碍j到障碍i的路线))
(其中j为位于障碍i左上方的障碍,即j可以通过合法路径到达i. 因此处理时先对障碍坐标排序).

类似题目对比总结:
至今为止做过五个类似的题:
1. CF-560E [Gerald and Giant Chess](http://www.codeforces.com/problemset/problem/560/E)
每次只能往右或下走,方案数比较好求,逆元求组合数(坐标较小).
2. UVALive-6916 [Punching Robot](http://acm.hust.edu.cn/vjudge/contest/97671#problem/K)
每次只能往右或下走,方案数比较好求,Lucas求组合数(坐标较大).
3. Gym-100379J [Move the (p, q)-knight to the corner!](http://acm.hust.edu.cn/vjudge/contest/87224#problem/H)
这个题跟本题几乎一样,走"类L"型路线,Lucas求组合数.
4. NOIP1997-普及组 [街道](http://oj.tsinsen.com/A1110)
这个题是坐标较小(50*50),障碍是一个矩形区域,对非障碍位置DP+高精度即可.
5. HDU-5794 [本题](http://acm.hdu.edu.cn/showproblem.php?pid=5794)
走"L"型路线,Lucas求组合数.


##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define eps 1e-8
#define maxn 150
#define mod 110119
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;

LL F[mod+10];

void init(LL p)

{

F[0] = 1;

for(int i = 1;i <= p;i++)

F[i] = F[i-1]i%p;

}

LL inv(LL a,LL m)

{

if(a == 1)return 1;

return inv(m%a,m)
(m-m/a)%m;

}

/初始化init(p),调用Lucas(m,n,p)计算C_m_n%p/

LL Lucas(LL n,LL m,LL p)

{

if(n < 0 || m < 0 || m > n)

return 0;

LL ans = 1;

while(n&&m)

{

LL a = n%p;

LL b = m%p;

if(a < b)return 0;

ans = ansF[a]%pinv(F[b]*F[a-b]%p,p)%p;

n /= p;

m /= p;

}

return ans;

}

LL get_ans(LL n, LL m)

{

return Lucas(m+n, m, mod);

}

LL m,n;

int k;

LL path[150];

struct node{

LL x,y;

bool operator < (const node& b)const {

if(x == b.x) return y < b.y;

return x < b.x;

}

}block[150];

int main(int argc, char const *argv[])

{

//IN;

init(mod);

int ca = 1;
while(scanf("%I64d %I64d %d", &n, &m, &k) != EOF)
{
memset(path, 0, sizeof(path));
memset(block, 0, sizeof(block));
for(int i=1; i<=k; i++){
scanf("%I64d %I64d", &block[i].x, &block[i].y);
}
block[k+1].x = n; block[k+1].y = m;
sort(block+1, block+k+2); for(int i=1; i<=k+1; i++) {
/*先求(1,1)到block_i的路线条数*/
LL step = block[i].x + block[i].y - 2;
if(step % 3) continue;
path[i] = get_ans(block[i].x - 1 - step/3, block[i].y - 1 - step/3); /*依次减去经过了其它障碍的路线数*/
for(int j=1; j<i; j++) {
LL step = block[i].x + block[i].y - block[j].x - block[j].y;
if(block[j].y > block[i].y || block[j].x > block[i].x || step % 3) continue; LL tmp = get_ans(block[i].x - block[j].x - step/3, block[i].y - block[j].y - step/3); path[i] = (path[i] + mod - (path[j] * tmp) % mod) % mod;
}
} printf("Case #%d: %I64d\n", ca++, path[k+1]%mod);
} return 0;

}

HDU 5794 A Simple Chess (容斥+DP+Lucas)的更多相关文章

  1. HDU 5794 - A Simple Chess

    HDU 5794 - A Simple Chess题意: 马(象棋)初始位置在(1,1), 现在要走到(n,m), 问有几种走法 棋盘上有r个障碍物, 该位置不能走, 并规定只能走右下方 数据范围: ...

  2. HDU 5794 A Simple Chess dp+Lucas

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 A Simple Chess Time Limit: 2000/1000 MS (Java/O ...

  3. hdu-5794 A Simple Chess(容斥+lucas+dp)

    题目链接: A Simple Chess Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  4. hdu5794 A Simple Chess 容斥+Lucas 从(1,1)开始出发,每一步从(x1,y1)到达(x2,y2)满足(x2−x1)^2+(y2−y1)^2=5, x2>x1,y2>y1; 其实就是走日字。而且是往(n,m)方向走的日字。还有r个障碍物,障碍物不可以到达。求(1,1)到(n,m)的路径条数。

    A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. HDU5794 A Simple Chess 容斥+lucas

    分析:转自http://blog.csdn.net/mengzhengnan/article/details/47031777 一点感想:其实这个题应该是可以想到的,但是赛场上并不会 dp[i]的定义 ...

  6. HDU 5794 A Simple Chess(杨辉三角+容斥原理+Lucas定理)

    题目链接 A Simple Chess 打表发现这其实是一个杨辉三角…… 然后发现很多格子上方案数都是0 对于那写可能可以到达的点(先不考虑障碍点),我们先叫做有效的点 对于那些障碍,如果不在有效点上 ...

  7. HDU 5794 A Simple Chess ——(Lucas + 容斥)

    网上找了很多人的博客,都看不太懂,还是大力学长的方法好. 要说明的一点是,因为是比较大的数字的组合数再加上mod比较小,因此用Lucas定理求组合数. 代码如下(有注释): #include < ...

  8. HDU 5794 A Simple Chess (Lucas + dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5794 多校这题转化一下模型跟cf560E基本一样,可以先做cf上的这个题. 题目让你求一个棋子开始在( ...

  9. HDU 5794 A Simple Chess Lucas定理+dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5794 题意概述: 给出一个N*M的网格.网格上有一些点是障碍,不能经过.行走的方式是向右下角跳马步.求 ...

随机推荐

  1. typeof和GetType的区别

    http://stackoverflow.com/questions/4537945/what-is-the-difference-of-getting-type-by-using-gettype-a ...

  2. iOS学习笔记: 使用CAShapeLayer创建带有空心区域的遮罩层

    CAShapeLayer是用来接受矢量Path,直接使用GPU来进行渲染的特殊图层.看下面效果: 对应代码: let markLayer = CAShapeLayer(); markLayer.fra ...

  3. 面试题_89_to_92_单元测试 JUnit 面试题

    89)如何测试静态方法?(答案)可以使用 PowerMock 库来测试静态方法. 90)怎么利用 JUnit 来测试一个方法的异常?(答案) 91)你使用过哪个单元测试库来测试你的 Java 程序?( ...

  4. ASP.NET中如何删除最近打开的项目和文件的记录

    ASP.NTET中总是保留最近打开的项目和文件的记录,甚至是已删除的它也不删.下面介绍几种删除的方法: 第一种:建立一个bat文件,以后双击即可清除,内置代码如下: @echo off@REG Del ...

  5. MySQL学习笔记一

    MySQL 学习笔记 一 一.数据库简单介绍 1. 按照数据库的发展时间顺序,主要出现了以下类型数据库系统: Ø 网状型数据库 Ø 层次型数据库 Ø 关系型数据库 Ø 面向对象数据库 上面4中数据库系 ...

  6. open_table

    /* Open a table. SYNOPSIS open_table() thd Thread context. table_list Open first table in list. acti ...

  7. C# 创建iis站点以及IIS站点属性,iis不能启动站点

    DontLog = False是否将客户端的请求写入日志文件 2011年04月09日 #region CreateWebsite 新增网站 public string CreateWebSite(st ...

  8. Java EE (14) -- SSH配置

    整合Spring与Struts1的三种方法总结 无论用那种方法来整合,第一步都是要装载spring的应用环境,有三种方式: #1. struts-config.xml <?xml version ...

  9. Nginx - 指定log_format,常用于 Awstats 分析

    1. vim /etc/nginx/nginx.conf (下面格式, Awstats 使用) log_format new_log '$remote_addr - $remote_user [$ti ...

  10. eclipse的使用

    类似于数据库系统的三层目录结构,一般而言IDE在逻辑上都有三层目录结构:工作空间(或解决方案) -> 工程 -> 文件. 当然,如果构建java project,那么目录结构是可以更深,因 ...