• 笔者在做下题时发现了对于for循环的重大理解错误

[NOIP2013 普及组] 计数问题
题目描述
试计算在区间 11nn 的所有整数中,数字 xx0x90\le x\le9)共出现了多少次?例如,在 111111 中,即在 1,2,3,4,5,6,7,8,9,10,111,2,3,4,5,6,7,8,9,10,11 中,数字 11 出现了 44 次。
输入格式
22 个整数 n,xn,x,之间用一个空格隔开。
输出格式
11 个整数,表示 xx 出现的次数。
样例输入 #1

1
11 1

样例输出 #1

1
4

提示
对于 100%100\% 的数据,1n1061\le n\le 10^60x90\le x \le 9

练习代码为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;
int main(){
int n,x,sum=0;
cin>>n>>x;
for(int i=1;i<=n;i++){
while (i)
{
if(i%10==x)
sum++;
i/=10;
}
}
cout<<sum;
return 0;
}

分析

程序运行时发现为死循环 ,调试过程中发现通过while循环i=0退出后,i重新被赋值为1,重现上一次循环。通过调试我发现自己在for循环理解出现问题。之前认为for(int i=1;i<=n;i++)固定的是,第一层为i=1,执行循环体后i就是2,现在才发现理解出现了很大的差错。关键在于i++,本题练习过程中i为循环变量,通过while循环改变i为0后,循环体结束下一步i++,i变为1,而不是理想中的2。
因此本题应该添加临时变量让替代循环变量。

##ACcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
using namespace std;
int main(){
int n,x,temp,sum=0;
cin>>n>>x;
for(int i=1;i<=n;i++){
temp=i;
while (temp)
{
if(temp%10==x)
sum++;
temp/=10;
}
}
cout<<sum;
return 0;
}