【整数】 n 位正整数的个数
请输出满足以下条件的 n 位正整数的个数:
要求该n位整数的从高位开始前 1 位可以被 1 整除,前 2 位可以被 22 整除,前 3 位可以被 33 整除,前 4 位可以被 4*4 整除……。即该整数前 k 位都可被 k 平方整除。
输入:
n(0<=n<9)
输出:
符合该条件的n位正整数的数量
本题可要使用数组!
样例:
序号 | 测试输入 | 期待的输出 | 额外进程 |
---|---|---|---|
1 | 1↵ | 9↵ | 0 |
2 | 2↵ | 22↵ | 0 |
3 | 8↵ | 0↵ | 0 |
思路
先观察样例,就会发现样例已经暗示我们了:当n>=8时,直接输出0
所以我们只需要考虑 1<=n<=7 的情况,那么最简单的方法当然是直接将这7个数算出来做一张映射表,直接一一对应:
代码1
#include <stdio.h>
int a[9] = {9,22,24,16,7,7,1,0,0};
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",a[n - 1]);
}
思路again
但是这样属实离谱了一点,虽然确实能过,也没啥没毛病,但万一老师想不给你分你也没办法,所以我们不妨试试直接暴力求解
代码2
#include <stdio.h>
#include <math.h>
main()
{
int n,i,j,counter = 0,p,flag;
scanf("%d",&n);
int l = pow(10,n-1),r = pow(10,n);
for(i = l;i < r;i ++)
{
for(j = 2,p = l,flag = 1;j <= n&&flag;j++)
{
p /= 10;
if((i/p)%(j*j) != 0) flag = 0;
}
if(flag) counter ++;
}
printf("%d\n",counter);
}
迭代法
通过观察不难发现,如果 ( x n . . . x 2 x 1 ) 10 (x_n...x_2x_1)_{10} (xn...x2x1)10满足条件,那么 ( x n . . . x 2 ) 10 (x_{n}...x_2)_{10} (xn...x2)10也一定满足条件,所以其实只要从n = 1的情况开始迭代就好了,每次只需判断上一次满足条件的数乘10后加上0-9是否满足条件:
#include <stdio.h>
int ori[30] = {0,1,2,3,4,5,6,7,8,9},sum[10] = {0,9},n;
int main()
{
scanf("%d",&n);
for(int i = 2;i < n + 1;i ++)
{
int temp[30] = {0};
for(int j = 1;ori[j];j ++)
{
int x = ori[j]*10,m = i*i;
for(int k = 0;k < 10;k ++)
if((x + k) % m == 0)
temp[++sum[i]] = x + k;
}
for(int k = 1;k < 31;k ++) ori[k] = temp[k];
}
printf("%d\n",sum[n]);
}