这个题是一个卡特兰数的裸题,为什么呢?因为可以通过划分来导出递推式从而判断是卡特兰数,然后直接上公式就行了。卡特兰数的公式见链接。
https://www.luogu.org/problemnew/solution/P2532
代码实现不难,就是一个高精乘|除低精。
题干:
题目描述
输入输出格式
输入格式:一个正整数N(1<=N<=500),表示阶梯的高度。
输出格式:一个正整数,表示搭建方法的个数。(注:搭建方法的个数可能很大)
输入输出样例
说明
40%的数据:1<=N<=20
80%的数据:1<=N<=300
100%的数据:1<=N<=500
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } struct node { int l,a[10001]; }; node init() { node h; h.l = 1; h.a[1] = 1; return h; } void mu(node &m,int b) { duke(i,1,m.l) { m.a[i] *= b; } duke(i,1,m.l) { if(m.a[i] >= 10) { m.a[i + 1] += m.a[i] / 10; m.a[i] %= 10; if(i == m.l) m.l++; } } // int tot = 1; while(m.a[m.l] > 10) { m.a[m.l + 1] += m.a[m.l] % 10; m.a[m.l] %= 10; m.l++; } } node dev(node m,int b) { node h; int tot = 0; lv(i,m.l,1) { tot = tot * 10 + m.a[i]; h.a[i] = tot / b; tot %= b; } h.l = m.l; while(h.a[h.l] == 0) h.l--; return h; } void output(node m) { lv(i,m.l,1) { printf("%d",m.a[i]); } return; } int n; int main() { node l; l = init(); read(n); duke(i,n + 2,n * 2) { mu(l,i); } duke(i,1,n) { l = dev(l,i); } // l = dev(l,6); output(l); return 0; }