目录
一、题目
二、更多示例
1、输入4048 输出275.
2、输入5821 输出400.
3、输入10000000 输出94400.
三、解题思路
1、构成好数的条件:一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数。
这意味着我们要去判断一个数的每一位,当奇数位的数字为奇数,偶数位时为偶数时,这个数就为好数。那我们怎么去判断呢?同时我们也要去看全部测试数据也即N的范围,以防N大于整型的存储范围(-2147483648 到 2147483647),1<=N<=10的7次方,因此N的大小未超范围,不用对N做出改变。
2、我们知道只要一个数对10进行取余操作,就可以获得这个数的最后一位。
int main()
{
int a = 2024;
int b = a % 10;
printf("%d", b);
return 0;
}
结果为4.
这时如果我们可以将这个数的最后一位去掉,然后继续进行取余操作,不就可以获得下一位的数字。恰好a=a/10;可以将最后一位去掉。而如果我们将上述操作放入循环中,我们就可以得到这个数的每一位。由此我们可以得到以下代码:
int main()
{
int n;
scanf("%d", &n);
int j = 1, b = 0;
while (n)
{
//b用来储存这个数的每一位
b = n % 10;
//j用来记录循环次数,也即j-1为这个数的位数。之所以令j=1,是为了对应这个数的奇数位和偶数位,为后续判断提供便利
j++;
//去除这个数的最后一位,当这个数只有一位时n=0,循环停止
n = n / 10;
}
return 0;
}
当我们可以得到这个数的每一位时,我们就可以对它的每一位进行判断,代码如下:
int main()
{
int n;
scanf("%d", &n);
int j = 1, b = 0,a=0,c=0;
while (n)
{
//b用来储存这个数的每一位
b = n % 10;
//判断这个数的奇数位是奇数偶数位是偶数,如果不是,则令a的值位1。
if ((j % 2 == 0 && b % 2 != 0) || (j % 2 == 1 && b % 2 != 1))
{
a=1;
}
//j用来记录循环次数,也即j-1为这个数的位数。之所以令j=1,是为了对应这个数的奇数位和偶数位,为后续判断提供便利
j++;
//去除这个数的最后一位,当这个数只有一位时n=0,循环停止
n = n / 10;
}
//记录达成好数条件的数的个数
if (a == 0)
{
c++;
}
return 0;
}
如果我们需要获得1~N内好数的个数,我们只需要在外加入一个循环即可。代码如下:
#include<stdio.h>
int main()
{
int N;
scanf("%d",&N);
int c=0;
for (int i = 1; i <= N; i++)
{
//令n=i是因为在后续操作中会改变n的值,从而死循环,所以不直接使i作为while循环的值
int j = 1,b=0,n=i,a=0;
while (n)
{
//b用来储存这个数的每一位
b = n % 10;
//判断这个数的奇数位是奇数偶数位是偶数,如果不是,则令a的值位1。
if ((j % 2 == 0 && b % 2 != 0) || (j % 2 == 1 && b % 2 != 1))
{
a = 1;
break;
}
//j用来记录循环次数,也即j-1为这个数的位数。之所以令j=1,是为了对应这个数的奇数位和偶数位,为后续判断提供便利
j++;
//去除这个数的最后一位,当这个数只有一位时n=0,循环停止
n = n / 10;
}
//记录达成好数条件的数的个数
if (a == 0)
{
c++;
}
}
//打印1-N的好数个数。
printf("%d", c);
return 0;
}
如此即可解决题目,我们也可以将内循环放入一个函数中,以使代码更好理解,美观。代码如下:
#include<stdio.h>
int css(int n)
{
int j=1,b=0;
while(n)
{
b=n%10;
if((j%2==0 && b%2!=0) || (j%2==1 && b%2!=1))
{
return 0;
}
j++;
n=n/10;
}
return 1;
}
int main()
{
int N,a=0;
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
a+=css(i);
}
printf("%d",a);
return 0;
}