CCF有趣的数(快速幂,递推)
来源:互联网 发布:手游代练软件 编辑:程序博客网 时间:2024/05/01 01:26
问题描述
我们把一个数称为有趣的,当且仅当:
1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次。
2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前。
3. 最高位数字不为0。
因此,符合我们定义的最小的有趣的数是2013。除此以外,4位的有趣的数还有两个:2031和2301。
请计算恰好有n位的有趣的数的个数。由于答案可能非常大,只需要输出答案除以1000000007的余数。
输入格式
输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000)。
输出格式
输出只有一行,包括恰好n 位的整数中有趣的数的个数除以1000000007的余数。
样例输入
4
样例输出
3
题解
一开始看这题真的是毫无头绪,后来尝试从一些很简单的问题入手,发现这个数只能以2开头,以1或3结尾,情况以下子少了很多,于是看看能不能递推,思路如下:
- 设长度为n(n>=4)的有趣的数个数为a[n]
- 考察a[n+1],
- 若这个数以1结尾
- 若前n位有0123,该情况数是a[n]
- 若前n位没有1,设第一个3出现的位数是k(1≤k≤n-1,从左往右从1开始),该种情况方法数为
- 若这个数以3结尾
- 若前n位有0123,该情况数是a[n]
- 若前n位没有3,情况略有不同,设第一个1出现的位数是k(2≤k≤n-1),该种情况方法数为
- 综上,a[n+1]=2a[n]+(n-2)*
- 但是直接这么算,n稍微大一点就会溢出,因此要随时取模
/*a[n+1]=2a[n]+(n-2)2^(n-1)-n+2*/#include<stdio.h>#define m 1000000007long long Pow(int n)/*计算2^n mod m*/{ if (n==1) return 2; long long half; half=Pow(n/2); if ((n&1)==0) return (half*half)%m; else return (((half*half)%m)*2)%m;}int main(void){ long long a=3; int i,n; scanf("%d",&n); for (i=4;i<n;i++) a=(a*2+(i-2)*Pow(i-1)-i+2)%m;/*可以保证在取余之前不会溢出,如果是int的话,(i-2)*Pow(i-1)可能会溢出*/ printf("%lld",a); return 0;}
- CCF有趣的数(快速幂,递推)
- CCF 有趣的数
- 【CCF】有趣的数
- ccf 有趣的数
- CCF 有趣的数
- CCF 有趣的数
- CCF 有趣的数
- ccf 有趣的数
- ccf有趣的数
- ccf-有趣的数
- 有趣的数-CCF
- CCF 有趣的数 【DP】
- 【CCF系列】有趣的数
- dp-ccf-有趣的数
- ccf 有趣的数 DP
- CCF CSP 有趣的数
- ccf201312-4有趣的数,递推
- ccf模拟题 有趣的数
- 将彩色图片转化为灰度图
- php.ini 的一点问题
- 将流信息转化成字符串
- fstream对象作为函数参数的问题汇总及解决方法
- hdu 4715 Difference Between Primes【筛法快速求素数表+思维】
- CCF有趣的数(快速幂,递推)
- Objective-C Runtime 运行时之五:协议与分类
- Java中的WeakReference讲解
- PHP开源框架 CodeIgniter
- 第七周项目一 (成员函数,友元函数和一般函数的区别)
- sudo免密码
- cocos2d Label无法正常显示中文
- Objective-C Runtime 运行时之六:拾遗
- 背包问题回溯法的递归实现(java)