[JZOJ3431]【GDOI2014模拟】网格
来源:互联网 发布:淘宝 i7主机 编辑:程序博客网 时间:2024/05/16 14:42
Description
某城市的街道呈网格状,左下角坐标为A(0, 0),右上角坐标为B(n, m),其中n >= m。现在从A(0, 0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左上方的点,即任何途径的点(x, y)都要满足x >= y,请问在这些前提下,到达B(n, m)有多少种走法。
Solution
不能穿过
然后我们取终点关于
可以发现,对于每条到对称点的路径,都碰到
或者说,它们是一一对应的。
所以答案就是随便走到终点的路径-随便走到对称点的路径。
然后再用组合数高精度之类的搞搞就好了。
Code
高精度码量略大
#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)#define mx 100000000using namespace std;struct arr{ long long a[2500];};arr a,k;int n,m;arr pl(arr a,arr b){ int la,lb,lc,i; arr c; la=a.a[0]; lb=b.a[0]; memset(c.a,0,sizeof(c.a)); fo(i,1,max(la,lb)) { c.a[i]=0; c.a[i]=c.a[i]+a.a[i]+b.a[i]; c.a[i+1]=c.a[i]/mx; c.a[i]=c.a[i]%mx; } lc=max(la,lb); if (c.a[lc+1]!=0) lc++; while(c.a[lc]==0&&lc>1) lc--; c.a[0]=lc; return c;}arr ti(arr a,int b){ int la,lc,i,j; arr c; la=a.a[0]; memset(c.a,0,sizeof(c.a)); j=0; fo(i,1,la) { c.a[i]=j+a.a[i]*b; j=c.a[i]/mx; c.a[i]=c.a[i]%mx; } c.a[la+1]=j; lc=a.a[0]+9; while(c.a[lc]==0&&lc>1) lc--; c.a[0]=lc; return c;}arr t2(arr a,arr b){ int la,lb,lc,i,j; arr c; la=a.a[0]; lb=b.a[0]; memset(c.a,0,sizeof(c.a)); fo(i,1,lb) { fo(j,1,la) { c.a[i+j-1]=c.a[i+j-1]+b.a[i]*a.a[j]; c.a[i+j]=c.a[i+j]+c.a[i+j-1]/mx; c.a[i+j-1]=c.a[i+j-1]%mx; } } lc=la+lb-1; if (c.a[lc+1]!=0) lc++; while(c.a[lc]==0&&lc>1) lc--; c.a[0]=lc; return c;}int larger(arr a,arr b){ if (a.a[0]>b.a[0]) return 1; if (a.a[0]<b.a[0]) return -1; { int i; fod(i,a.a[0],1) { if (a.a[i]>b.a[i]) return 1; if (a.a[i]<b.a[i]) return -1; } return 0; }}arr div(arr a,int k){ int i,la=a.a[0]; fod(i,la,2) { if (a.a[i]%k!=0) a.a[i-1]+=(a.a[i]%k)*mx; a.a[i]=a.a[i]/k; } a.a[1]=a.a[1]/k; if (a.a[la]==0) a.a[0]--; return a;}arr turn(int i){ int j; arr c; c.a[0]=floor(log(i)/log(mx))+1; fo(j,1,c.a[0]) { c.a[j]=i%mx; i/=mx; } return c;}int main(){ freopen("map.in","r",stdin); int i; cin>>n>>m; a.a[0]=a.a[1]=1; fo(i,n+2,n+m) { a=ti(a,i); } a=ti(a,n+1-m); fo(i,2,m) a=div(a,i); fod(i,a.a[0],1) { int p=mx/10; while(a.a[i]<p&&p>1&&i!=a.a[0]) { printf("0"); p/=10; } printf("%d",a.a[i]); } cout<<endl; }
0 0
- [JZOJ3431]【GDOI2014模拟】网格
- 【GDOI2014模拟】网格
- 【GDOI2014模拟】网格
- 【GDOI2014模拟】网格
- 【GDOI2014模拟】网格
- 【GDOI2014模拟】网格 题解+代码
- JZOJ.3431【GDOI2014模拟】网格 解题报告
- [bzoj3754][GDOI2014模拟]Tree
- 【GDOI2014模拟】服务器
- 【GDOI2014模拟】Tree
- 【GDOI2014模拟】服务器
- 【GDOI2014模拟】Tree
- 3432. 【GDOI2014模拟】服务器
- 【GDOI2014模拟】旅行(水法)
- 【GDOI2014模拟】Pty爬山
- 【GDOI2014模拟】雨天的尾巴
- [JZOJ3401]【GDOI2014模拟】Pty爬山
- 【GDOI2014模拟】旅行 题解&代码
- 2016.6.11初中部模拟赛总结
- php类文件命名规范
- FindJpg(3)-图片加载中的线程池应用
- 手机开发实战143——RGB介绍2
- T1: 城墙(sandcas.pas/cpp)
- [JZOJ3431]【GDOI2014模拟】网格
- android onTouch()与onTouchEvent()的区别
- 11. 配置ContextPath【从零开始学Spring Boot】
- C++考试总结
- 手机开发实战144——YUV介绍
- 手机开发实战145——ALPHA介绍
- 12. 改变JDK编译版本【从零开始学Spring Boot】
- Linux系统启动程序和Linux常用命令整理
- 手机开发实战146——BMP介绍1