華為OJ上挑7的練習題解決過程
挑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’,雖然有的這兩類情況有交集的存在,但是這種方式卻不會重複統計,也不會遺漏某些情況。