在所有的N 位数中,有多少个数中有偶数个数字3 ?由于结果可能很大,你只需要输出这个答案对12345 取余的值。,用c语言编写
时间: 2024-02-18 08:02:59 浏览: 209
以下是使用 C 语言实现的代码:
```c
#include <stdio.h>
#include <string.h>
const int MOD = 12345;
const int MAX_DIGIT = 20;
int f[MAX_DIGIT][2][MAX_DIGIT];
int count(int n) {
char s[MAX_DIGIT];
sprintf(s, "%d", n); // 将数字转为字符串
int len = strlen(s);
memset(f, 0, sizeof(f));
f[len][1][0] = 1;
for (int i = len - 1; i >= 0; i--) {
int upper_bound = s[i] - '0';
for (int j = 0; j <= 1; j++) {
for (int k = 0; k <= len / 2; k++) {
int& dp = f[i][j][k];
for (int d = 0; d < 10; d++) {
if (j == 0 && d > upper_bound) break;
if (d == 3) {
dp = (dp + f[i + 1][j && (d == upper_bound)][k ^ 1]) % MOD;
dp = (dp + f[i + 1][j && (d == upper_bound)][k]) % MOD;
} else {
dp = (dp + f[i + 1][j && (d == upper_bound)][k]) % MOD;
}
}
}
}
}
return f[0][0][0];
}
int main() {
int n;
scanf("%d", &n);
printf("%d\n", count(n));
return 0;
}
```
这里使用 `sprintf()` 函数将数字转为字符串,便于数位 DP 的实现。同时,由于数字的位数可能很大,我们需要使用一个二维数组 `f` 来存储状态,它的第一维表示当前正在考虑的数位,第二维表示当前选定的数字是否达到了上界,第三维表示当前已经匹配的数字 3 的个数。在转移时,我们枚举当前数位上的数字,考虑选或不选 3 两种情况,并根据上界判断是否能选当前数字。最终答案即为 $f_{0,0,0}$,也就是最高位为 0,当前已经选定的数字 3 的个数为 0 的方案数。
注意在转移时需要使用取模运算防止溢出。
阅读全文