A Simple Chess
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 667 Accepted Submission(s): 168
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 .<br>Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle.<br>I want you to tell me, There are how may ways the chess can achieve its goal. </div><div class=panel_bottom> </div><br><div class=panel_title align=left>Input</div> <div class=panel_content>The input consists of multiple test cases.<br>For each test case:<br>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.<br>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)
.</div><div class=panel_bottom> </div><br><div class=panel_title align=left>Output</div> <div class=panel_content>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
.
(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 .<br>Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle.<br>I want you to tell me, There are how may ways the chess can achieve its goal. </div><div class=panel_bottom> </div><br><div class=panel_title align=left>Input</div> <div class=panel_content>The input consists of multiple test cases.<br>For each test case:<br>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.<br>Then follow r lines, each lines have two integers,
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
Author
UESTC
Source
题目大意:
给一个
n∗m
的方格,让你以象棋中”马”的方式从
(1,1)
点走到
(n,m)
点的方法数对
MOD
取模,(“马”的方式只能向右上方),中间会有一些障碍。
解题思路:
卢卡斯定理加上容斥,
(1,1)
点到
(n,m)
点,如果中间有
(x,y)
点的障碍的话,那么一定是
(1,1)
点到
(n,m)
点的方法数
c
My
Code:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
typedef long long LL;
const LL MOD = 110119LL;
struct Node
{
LL x, y, s;
} node[105];
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=1;
while(b)
{
if(b&1) ret=(ret*a)%MOD;
a=(a*a)%MOD;
b>>=1;
}
return ret;
}
LL fac[1000005];
void Get_Fact(LL p)
{
fac[0]=1;
for(int i=1; i<=p; i++)
fac[i]=(fac[i-1]*i)%p;
}
LL Lucas(LL n,LL m,LL p)
{
LL ret=1;
while(n&&m)
{
LL a=n%p,b=m%p;
if(a<b) return 0;
ret=(ret*fac[a]*PowMOD(fac[b]*fac[a-b]%p,p-2,p))%p;
n/=p;
m/=p;
}
return ret;
}
int main()
{
LL n,m;
int r;
int Case=1;
Get_Fact(MOD);
while(scanf("%lld%lld%d",&n,&m,&r)!=EOF)
{
int tot=0;
LL sum=0;
int flag=0;
if((n+m+1)%3==0)
{
LL s=(n+m+1)/3;
if(n>=s&&m>=s)
{
LL t=n;
n=2*s-m;
m=2*s-t;
}
else
{
flag=1;
}
}
else
{
flag=1;
}
for(int i=0; i<r; i++)
{
LL x,y;
scanf("%lld%lld",&x,&y);
if((x+y+1)%3==0)
{
LL s=(x+y+1)/3;
if(x>=s&&y>=s)
{
node[tot].x=2*s-y;
node[tot].y=2*s-x;
if(node[tot].x<=n&&node[tot].y<=m)
tot++;
}
}
}
if(flag==1)
{
printf("Case #%d: %lld\n",Case++,sum);
continue;
}
if(tot>0)
sort(node,node+tot,cmp);
sum=Lucas(n+m-2,n-1,MOD)%MOD;
for(int i=0; i<tot; i++)
{
node[i].s=Lucas(node[i].x+node[i].y-2,node[i].x-1,MOD)%MOD;
}
for(int i=0; i<tot; i++)
{
LL tt=Lucas(n-node[i].x+m-node[i].y,m-node[i].y,MOD);
for(int j=i+1; j<tot; j++)
{
if(node[j].y>=node[i].y)
{
LL d1=node[j].y-node[i].y;
LL d2=node[j].x-node[i].x;
node[j].s=(node[j].s-(node[i].s*Lucas(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);
}
}