NOIP 普及组初赛 · NOIP 2009 普及组初赛试题 第 24 题

阅读程序 · 答案 416 · 考点:一维数组、运算符与表达式、顺序结构、循环结构

← 整套速查表 NOIP 普及组初赛 全部真题

题目

阅读程序写结果:

#include <iostream>
using namespace std;
int main()
{
	int a[3],b[3];
	int i,j,tmp;
	for (i=0;i<3;i++)
		cin >> b[i];
	for (i=0;i<3;i++)
	{
		a[i]=0;
		for (j=0;j<=i;j++)
		{
			a[i]+=b[j];
			b[a[i]%3]+=a[j];
		}
	}
	tmp=1;
	for (i=0;i<3;i++)
	{
		a[i]%=10;
		b[i]%=10;
		tmp*=a[i]+b[i];
	}
	cout << tmp << endl;
	return 0;
}

输入:2 3 5

答案:416

考点

一维数组运算符与表达式顺序结构循环结构

解题思维

这道题考的是顺序、循环和一维数组的综合运用,核心是数组元素在循环中被动态修改。拿到题先别急着写代码,把输入2,3,5代入,像真人一样一步步在草稿纸上推a和b的变化,尤其注意b[a[i]%3]这一句会覆盖旧值,这是解题的关键。

常见错误

最容易栽跟头的地方就是数组b在循环里被反复修改,很多人以为b数组是固定不变的,或者只注意到a[i]的累加,却忽略了b[a[i]%3]里的a[i]可能指向同一个下标(比如i=0时a[0]=2,i=1时a[1]=5,5%3=2,又指向b[2])。如果没盯住这个下标变化,后面的b[2]就会算错,导致最后tmp乘积完全不对。另外,最后取余操作a[i]%=10和b[i]%=10是独立对每个元素做的,不是对整个数组求和再取余,这点也容易看错。

详细解析(节选)

考点与命题视角

这道题把顺序结构、循环结构和一维数组揉在一起考,属于NOIP普及组初赛里那种‘看似简单实则细节多’的类型。命题人挖坑的套路很明确:先让你模拟一个双重循环,然后在循环里动态修改数组元素,最后再叠加取余和乘法。这种题不考算法复杂度,就考你能不能像计算机一样老老实实按步骤走,每一步都算对。

概念拆解:数组与取余

数组a[3]和b[3]都是整型,下标从0到2。循环里的关键操作是b[a[i]%3]+=a[j]。这里的a[i]%3是一个下标,它会根据当前i和之前计算出的a[i]的值在0,1,2之间跳动。比如当i=0时,a[0]算出来是2,那么a[0]%3就是2,所以会去修改b[2];当i=1时,a[1]算出来是5,5%3等于2,还是修改b[2];当i=2时,a[2]算出来是17,17%3也等于2,还是修改b[2]。这意味着b[2]在整个循环里会被累加三次,而b[0]和b[1]只会被读,不会被写。

同考点真题

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