题目链接:

http://acm.hust.edu.cn/vjudge/problem/96344

Punching Robot

Time Limit: 1000MS
64bit IO Format: %lld & %llu

题意

在n*m的棋盘上有k个障碍物,并且这k个障碍物周围8个格子也都是障碍物,问从(1,1)到(n,m)总共有多少种不经过障碍物任何的走法(每次只能向下走或者向右走。

题解

这题和之前的一道题基本相同:点这里

由于给的质数比较小,所以不能保证互质(比如说mod与mod就不会互质了),所以求逆的时候会出问题,可以考虑求阶乘的时候单独把997这个因子全部提出来,并且记录下个数,单独讨论一下就可以做了。

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=2e6+10;
const int mod=997; int n,m,k;
LL dp[111],fac[maxn];
int num[maxn];
VPII robot; void gcd(LL a,LL b,LL& d,LL& x,LL& y){
if(!b){ d=a; x=1; y=0; }
else{ gcd(b,a%b,d,y,x); y-=x*(a/b); }
} LL Inv(LL a,int mod){
LL d,x,y;
gcd(a,mod,d,x,y);
return d==1?(x+mod)%mod:-1;
} LL get_C(int n,int m){
if(n<m||n<0||m<0) return 0;
if(num[n]!=num[m]+num[n-m]) return 0;
return fac[n]*Inv(fac[m]*fac[n-m]%mod,mod)%mod;
} LL calc(int i,int j){
int n=robot[j].X-robot[i].X;
int m=robot[j].Y-robot[i].Y;
if(n<0||m<0) return 0;
return get_C(n+m,n);
} void pre(){
clr(num,0);
fac[0]=1;
for(int i=1;i<maxn;i++){
int x=i;
num[i]+=num[i-1];
while(x%mod==0){
x/=mod;
num[i]++;
}
fac[i]=fac[i-1]*x%mod;
}
} void init(){
clr(dp,0);
robot.clear();
} int main() {
pre();
int tc,kase=0;
scf("%d",&tc);
while(tc--){
scf("%d%d%d",&n,&m,&k);
init();
int su=1;
for(int i=1;i<=k;i++){
int x,y;
scf("%d%d",&x,&y);
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
int a=x+dx,b=y+dy;
robot.pb(mkp(a,b));
if(a==1&&b==1||a==n&&b==m){
su=0;
}
}
}
}
if(!su){ puts("0"); continue; }
robot.pb(mkp(1,1));
robot.pb(mkp(n,m));
sort(robot.begin(),robot.end()); for(int i=1;i<robot.sz();i++){
dp[i]=calc(0,i);
for(int j=1;j<i;j++){
dp[i]=(dp[i]-dp[j]*calc(j,i)%mod)%mod;
}
dp[i]=(dp[i]+mod)%mod;
}
printf("Case #%d: %lld\n",++kase,dp[robot.sz()-1]);
}
return 0;
} //end-----------------------------------------------------------------------

其实直接上卢卡斯就不会有不互质的困扰啦!(跑的更快!)

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=2e6+10;
const int mod=997; int n,m,k;
LL dp[111],fac[mod+10],facinv[mod+10],inv[mod+10];
VPII robot; LL get_C(int n,int m){
if(n<m||n<0||m<0) return 0;
return fac[n]*facinv[n-m]%mod*facinv[m]%mod;
} LL Lucas(LL n,LL m,LL p){
if(m==0) return 1LL;
return get_C(n%p,m%p)*Lucas(n/p,m/p,p)%p;
} LL calc(int i,int j){
int n=robot[j].X-robot[i].X;
int m=robot[j].Y-robot[i].Y;
if(n<0||m<0) return 0;
return Lucas(n+m,n,mod);
} void pre(){
fac[0]=fac[1]=1;
facinv[0]=facinv[1]=1,inv[1]=1;
for(int i=2;i<mod;i++){
fac[i]=fac[i-1]*i%mod;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
facinv[i]=facinv[i-1]*inv[i]%mod;
}
} void init(){
clr(dp,0);
robot.clear();
} int main() {
pre();
int tc,kase=0;
scf("%d",&tc);
while(tc--){
scf("%d%d%d",&n,&m,&k);
init();
int su=1;
for(int i=1;i<=k;i++){
int x,y;
scf("%d%d",&x,&y);
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
int a=x+dx,b=y+dy;
robot.pb(mkp(a,b));
if(a==1&&b==1||a==n&&b==m){
su=0;
}
}
}
}
if(!su){ puts("0"); continue; }
robot.pb(mkp(1,1));
robot.pb(mkp(n,m));
sort(robot.begin(),robot.end()); for(int i=1;i<robot.sz();i++){
dp[i]=calc(0,i);
for(int j=1;j<i;j++){
dp[i]=(dp[i]-dp[j]*calc(j,i)%mod)%mod;
}
dp[i]=(dp[i]+mod)%mod;
}
printf("Case #%d: %lld\n",++kase,dp[robot.sz()-1]);
}
return 0;
} //end-----------------------------------------------------------------------

UVALive - 6916 Punching Robot Lucas+dp的更多相关文章

  1. UVALive 6916 Punching Robot dp

    Punching Robot 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid= ...

  2. HDU 5794:A Simple Chess(Lucas + DP)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5794 题意:让一个棋子从(1,1)走到(n,m),要求像马一样走日字型并只能往右下角走.里 ...

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

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

  4. Codeforces Round #313 (Div. 2) E. Gerald and Giant Chess (Lucas + dp)

    题目链接:http://codeforces.com/contest/560/problem/E 给你一个n*m的网格,有k个坏点,问你从(1,1)到(n,m)不经过坏点有多少条路径. 先把这些坏点排 ...

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

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

  6. hdu_5794_A Simple Chess(lucas+dp)

    题目链接:hdu_5794_A Simple Chess 题意: 给你n,m,从(1,1)到(n,m),每次只能从左上到右下走日字路线,有k(<=100)的不能走的位置,问你有多少方案 题解: ...

  7. UVALive 4261——Trip Planning——————【dp+打印路径】

    Trip Planning Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Stat ...

  8. UVALive 6491 You win! 状态DP

    这个题目上周的对抗赛的,美国2013区域赛的题目,上次比赛真惨,就做出一道题,最多的也只做出两道,当时想把这题做出来,一直TLE. 这个题目用挂在Hunnu OJ的数据可以过,但UVALive上死活过 ...

  9. UVaLive 7143 Room Assignment (组合数+DP)

    题意:有 n 个客人,m个房间,每个房间可住ci个人,这 n 个人中有 t 对双胞胎,sum{ci}  = n 问你有多少种住房方法. 析:计数DP,dp[i][j] 表示前 i 个房间,还剩下 j ...

随机推荐

  1. 小程序中 function (res)的理解

    刚看到小程序里面一段代码 success: function (res) { console.log('搜索结果:'); console.log(res); wx.hideToast(); if (r ...

  2. 微信小程序页面3秒后自动跳转

    setTimeout() 是属于 window 的方法,该方法用于在指定的毫秒数后调用函数或计算表达式. 语法格式可以是以下两种:   setTimeout(function () { // wx.r ...

  3. PHP中实现中文字串截取无乱码的方法

    [本文转自独占神林的日志:链接:http://yuninglovekefan.blog.sohu.com/176021361.html] 在PHP中,substr()函数截取带有中文字符串的话,可能会 ...

  4. 【深度优先搜索】NOIP2017_D2T1 洛谷3958奶酪

    这道题的写法大体有两种:大法师DFS和并查集,两种算法都不难,本篇博客主要讲解DFS,而且测试数据特水,连个剪枝都不用都可以过. 题目描述[luogu传送门] 现有一块大奶酪,它的高度为 h,它的长度 ...

  5. Go 入门 - 包,函数和变量

    主要内容来自中文版的官方教程Go语言之旅 目的为总结要点 包,函数和变量 包 import 语法,多个用括号换行扩起,包之间不需要间隔符,用引号引起 import ( "fmt" ...

  6. 07-容器类Widget

    容器类Widget 容器类Widget一般只是包装其子Widget,对其添加一些修饰(补白或背景色等).变换(旋转或剪裁等).或限制(大小等) Padding Padding可以给其子节点添加补白(填 ...

  7. 20155224 2016-2017-2 《Java程序设计》第3周学习总结

    20155224 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 本周学习量比前两周大,代码量也比较多,还出现了挺多术语,都要慢慢查. 第四章 第四章主要学习 ...

  8. 20155338 ch02 ch03课下作业

    20155338 ch02 ch03课下作业 要求: 1.补充完成课上测试(不能只有截图,要有分析,问题解决过程,新学到的知识点) 课上测试-3-ch02 1.编写一个程序 "week060 ...

  9. 百度地图api 常用 例子

    功能一:获取map地图窗口的可视区域: var map = new BMap.Map("allmap");            // 创建Map实例 map.centerAndZ ...

  10. 【BZOJ4553】[HAOI2016&TJOI2016]序列

    [BZOJ4553][HAOI2016&TJOI2016]序列 题面 bzoj 洛谷 题解 一定要仔细看题啊qwq... 我们设$mn[i],mx[i]$表示第$i$个位置上最小出现.最大出现 ...