<考试题> codevs 5251 WYW的数字金字塔
2017-10-23 15:04
232 查看
*PS:原来暴力优化优化是可以过的么qwq,ljoj 数据手动测并没有T。。。最后默默的吐槽一句,附上一个金字塔的图是因为怕我们没有见过吗。。。
go to the problem
wyw用随机数生成器生成了一个小于n且大于1的正整数k。
wyw找来一张白纸,他在白纸的最低端写下了这个数字n。
wyw在n的上面紧挨着写下了一个正整数a1,a1满足不大于n/k,
wyw又在a1上面写下了一个正整数a2,满足a2不大于a1/k,
时间过了t…
wyw在ah-1的上面写下了一个正整数ah,满足ah不大于ah-1/k
wyw已经无法在ah的上方写出不大于ah/k的数字了
这时,wyw就已经写好了一个高度为h(这里应该为h+1)的数字金字塔
wyw可以按照这个规则写出好多符合条件的数字金字塔。
试问:wyw一共能够写出多少种数字金字塔?wyw能写出的所有的数字金字塔中最高的金字塔的高度是多少?
注意:由于答案可能较大,所以对每一组数据请输出答案对p取模后的值。
后面跟着T组数据,每组数据仅一行,包含了一个正整数n和k,意义如题目所述
6 2
20 3
样例说明:以20 3这组数据为例,wyw能写出的所有金字塔如下
1 1
代码
4000
go to the problem
题目描述 Description
wyw有一个数字n,他要用这个数字写出一个数字金字塔。wyw用随机数生成器生成了一个小于n且大于1的正整数k。
wyw找来一张白纸,他在白纸的最低端写下了这个数字n。
wyw在n的上面紧挨着写下了一个正整数a1,a1满足不大于n/k,
wyw又在a1上面写下了一个正整数a2,满足a2不大于a1/k,
时间过了t…
wyw在ah-1的上面写下了一个正整数ah,满足ah不大于ah-1/k
wyw已经无法在ah的上方写出不大于ah/k的数字了
这时,wyw就已经写好了一个高度为h(这里应该为h+1)的数字金字塔
wyw可以按照这个规则写出好多符合条件的数字金字塔。
试问:wyw一共能够写出多少种数字金字塔?wyw能写出的所有的数字金字塔中最高的金字塔的高度是多少?
注意:由于答案可能较大,所以对每一组数据请输出答案对p取模后的值。
输入描述 Input Description
输入数据的第一行包含两个正整数T、p,表示有T组测试数据,p的意义如题目所述后面跟着T组数据,每组数据仅一行,包含了一个正整数n和k,意义如题目所述
输出描述 Output Description
输出数据一共n行,每行两个整数,表示答案对p取模后的值样例输入 Sample Input
2 26 2
20 3
样例说明:以20 3这组数据为例,wyw能写出的所有金字塔如下
样例输出 Sample Output
1 11 1
数据范围及提示 Data Size & Hint
Solution 1 暴力
(codevs 上会T3个点,但手动测了测根本就没T 。。。qwq)代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; long long T,k; long long n=0,p,cnt; int f[50000010]; int main() { scanf("%lld%lld",&T,&p); while(T--) { scanf("%lld%lld",&n,&k); int z=n/k; f[0]=0; for(int i=1;i<=2*k-1;++i) f[i]=1; // 2*k之前都只能放一个,只有一种方案。 for(int i=2*k;i<=z+1;++i) f[i]=0; for(int i=2*k;i<=z;++i) // 递推 for(int j=i/k;j>=1;--j) f[i]=(f[i]%p+f[j]%p)%p; for(int i=1;i<=z;++i) f[0]=(f[0]%p+f[i]%p)%p; //用0存防止爆空间 if(!f[0]) ++f[0]; // 只能放n也是一种方案 printf("%lld ",f[0]%p); cnt=1; while(n/k) { n/=k; cnt=(cnt+1)%p; } printf("%lld\n",cnt); } return 0; }
Solution 2 DP
代码#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; long long T,P,n,k; int S[500020]; int main() { scanf("%lld%lld",&T,&P); S[0]=S[1]=1; while(T--) { scanf("%lld%lld",&n,&k); int N=n/k,ans2=1; for(int i=2;i<=N;++i) S[i]=(S[i-1]+S[i/k])%P; while(n/k) { n/=k; ans2=(ans2+1)%P; } printf("%d %lld\n",S ,ans2); } return 0; } /* 用数组s[i]表示以不大于i为底的数字所达到的方案数之和。 F[i]表示以某一数字(i)为底的方案数。 而F[i]恰好为s[i/k]. 所以方程式为:s[i] = s[i–1] + f[i]; (类似前缀和) PS:这里直接把f换成了s */
4000
相关文章推荐
- codevs 5251 WYW的数字金字塔
- <考试题> codevs 5440 运输计划 (二分+lca+dfs序+树上差分)
- <DP>codevs 2189 数字三角形w
- <线段树系列1> codevs 1080 线段树练习
- <C语言>输入某个大写字母,产生一个金字塔图案。(字符与数字间的转换)
- <线段树系列2> codevs 1082 线段树练习2
- <线段树系列3> codevs 1082 线段树练习3
- <矩阵快速幂>codevs 3332 数列
- <线段树系列4> codevs 4927 线段树练习5
- <二分答案+spfa验证>codevs 1183 泥泞的道路
- <单调栈/悬线法>codevs 2491 玉蟾宫 1159 最大全0子矩阵
- <错排>codevs 1697 ⑨要写信
- <tarjan||拓扑>codevs 2066 三角恋
- <倍增lca>codevs 3305 水果姐逛水果街Ⅱ
- <kmp>codevs 1404 字符串匹配
- 【BZOJ1009】【codevs2325】GT考试,kmp+矩阵加速DP
- <状压DP>codevs 2451 互不侵犯
- <背包DP>codevs 1684 垃圾陷阱
- <序列DP>codevs 4748 低价购买
- <序列DP>codevs 2980 买帽子