华为OJ上挑7的练习题解决过程

时间:2022-11-06 11:27:31

    挑7练习题的介绍,输入一个整数N,给定了整数N范围是1到30000,要求统计出从1到N范围内所有与7相关数字的个数,与7相关的数字定义为,是7的倍数或者数字中含有7,比如17和71均含有‘7’。

    看到该题目上的很多提交程序者,都很疑惑为什么提交的程序会是结果错误。在第一次提交的时候,我也出现了类似的错误,原因是对于7相关的数字进行逻辑判断划分不正确,导致了某些不该被统计的数字,错误的当做了与7相关。后来看那些有疑惑的提交者,大多犯了这种错误,有的是统计了不该统计的数字,有的是遗漏了某些数字,其根源是在逻辑判断划分上出现了遗漏或错误。

    首先说一下我看到该题目的解题思路吧。 首先我想到的方法,与7相关的数字可以分为两类,是7的倍数和数位中含有7,并且这两类数字有交集,比如70既是7的倍数,数位也含有7。对于7的倍数的判断可以采用求余的方法来判断,而对于数位中含有7的判断,如果7在个位,则可以采用与10求余的方法来判断,但是如果7在其他位上,则不能直接采用这种方法来判断,需要通过一种手段,来把7移到个位再判断,这里我采用的是每次将数字除以10来实现。先看看我第一次提交的代码,其中在逻辑判断上,犯了一点错误。

代码一:

#include"stdio.h"
void main()
{
int num=0,i=0,N=0,k=0;
scanf("%d",&N);
for (i=1;i<=N;i++)
{
k=i;
while(k>0)
{
if (k%7==0||k%10==0)    ............①
{
num++;
break;
}
else
{
k=k/10;
}
}
}
printf("%d\n",num);
}

    在上面的代码一种,错误就存在①处的判断逻辑,会导致一个不应该统计的数字被统计了,例如211不是7的倍数,也不含有‘7’,但是在while循环的第二次中,会出现21%7=0的情况,导致被统计了。因此结果就不正确了,而这种错误,对于某些给定的数字范围却不能发现。后来我修改了代码,改正了这个错误,再次提交,结果就正确了。下面给出第二次提交的代码:

代码二:

#include"stdio.h"
void main()
{
int num=0,i=0,N=0,k=0;
scanf("%d",&N);
for (i=1;i<=N;i++)
{
if (i%7==0)
{
num++;
}
else
{
k=i;
while (k>0)
{
if (k%10==7)
{
num++;
break;
}
else
k=k/10;
}
}
}
printf("%d\n",num);
}

    代码二的思路是,首先进行判断是否是7的倍数,如果不是7的倍数,才去判断是否含有‘7’,虽然有的这两类情况有交集的存在,但是这种方式却不会重复统计,也不会遗漏某些情况。