NOIP 提高组初赛 · NOIP 2009 提高组初赛试题 第 26 题

选择题 · 答案 0.(384615) · 考点:一维数组、循环结构

← 整套速查表 NOIP 提高组初赛 全部真题

题目

#include <iostream>
using namespace std;

int main()
{
	int n,m,i,j,p,k;
	int a[100],b[100];
	cin >> n >> m;
	a[0]=n;
	i=0;
	p=0;
	k=0;
	do
	{
		for (j=0;j<i;j++)
			if (a[i]==a[j])
			{
				p=1;
				k=j;
				break;
			}
		if (p)
			break;
		b[i]=a[i]/m;
		a[i+1]=a[i]%m*10;
		i++;
	}while (a[i]!=0);
	
	cout << b[0] << ".";
	for (j=1; j<k; j++)
		cout << b[j];
	if (p)
		cout << "(";
	for (j=k;j<i;j++)
		cout << b[j];
	if (p)
		cout << ")";
	cout << endl;
	return 0;
}

输入:5 13 输出:_________

答案:0.(384615)

考点

一维数组循环结构

解题思维

这题考循环节检测。拿到题先别急着算,盯着数组a存余数、b存商那几行,明白它在模拟竖式除法;用‘余数重就停’的思路,一步步手算5÷13,就能直接写出答案。

常见错误

最容易掉进两个坑:一是把a[1]当成循环起点,忽略p=1时k=j=1,导致输出格式变成0.(384615)却漏掉循环标记,或者误以为要输出0.384615384615…;二是死算到a[7]=50才反应过来循环,却忘了题目给的输出格式里,一旦检测到循环(p=1),必须在循环节前后加括号,且只输出到i-1,所以别把b[6]也打出来。

详细解析(节选)

考点与命题视角

这题属于循环结构与一维数组的综合应用,命题人想考的是:能不能读懂一段模拟竖式除法的代码,并准确判断何时出现循环。这类题在NOIP提高组初赛里很常见——给一段看似复杂的循环,让你填输出或找规律。命题人喜欢在数组下标、循环条件、break的位置挖坑,比如这里p=1时k=j,意味着第一次发现重复余数时,k就指向那个重复的位置,而输出时要从k开始重复部分。如果你没注意p的作用,很容易把输出截断或多加一位。

概念人话解释

程序里有两个数组:a用来存每次的余数,b用来存每次的商(小数位)。i是循环计数器,j用来检查当前余数a[i]之前有没有出现过。p是个标记,只要发现重复就置1,然后break跳出内层循环;k记录第一次重复出现的位置。整个逻辑就是:做除法,每算一位,把余数存起来,如果这个余数以前出现过,说明后面会重复,循环结束。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断