<center style="color:rgba(0,0,0,.87);font-family:Lato, 'Helvetica Neue', Arial, Helvetica, sans-serif;font-size:14px;">
</center>
问题 : 恩爱的回文数
时间限制: 2 Sec 内存限制: 128 MB</center>
题目描述
因为最近身边脱单的人太多了,于是 GBX 狂热的迷上了回文数。因为回文数看起来就像是一对恩爱狗站在一起,他希望自己将来也有那么一天(虽然并不可能)。这一天他突然想到一个问题,长度不大于 n 的自然数中有多少是回文数?因为数据很大,所以最后的结果请对 1000000007 取模。
输入
输入一个 T(T ≤ 100)表示 T 组数据。
对于每组数据输入一个整数 n(1 ≤ n ≤ 10^6 )。
对于每组数据输入一个整数 n(1 ≤ n ≤ 10^6 )。
输出
对于每组数据输出一个整数表示回文数的个数对 1000000007 取模的余数。
样例输入
2
1
2
样例输出
10
19
解题思路
这道题很容易想的,一位数就0~9,共10种;两位数因对称且首位不能为0就1~9,共9种;三位数首位9种情况,第二位10种情况(可以为0),最后一位和首位对称,不考虑,共9*10^1种;四位数 首位9种情况,第二位10种情况(可以为0),最后两位和前两位对称,不考虑,共9*10^1种。从这里我们发现n位数共有9*10^((n-1)/2)种(n=1除外),最后把前面的所有情况加起来就可以了。具体见代码:
#include <stdio.h>
#define N 1000010
const int MOD = 1000000007;
unsigned long long pow[N / 2], sum[N];
int main() {
unsigned int t, n, i;
pow[0] = 1;
sum[1] = 10;
for (i = 1; i < (N - 1) / 2; i++)
pow[i] = (pow[i - 1] * 10) % MOD;
for (i = 2; i < N; i++)
sum[i] = (sum[i - 1] + 9 * pow[(i - 1) / 2]) % MOD;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
printf("%lld\n", sum[n]);
}
return 0;
}