2019 CSP-J 阅读程序
1阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 √,错误填 ×。除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分)
假设输入的n和m都是正整数,x和y都是在[1, n]的范围内的整数,完成下面的判断题和选择题
#include<cstdio>
using namespace std;
int n, m;
int a[100], b[100];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)//对a和b数组的前n项置为0
a[i] = b[i] = 0;
for (int i = 1; i <= m; ++i) {//录入m个x和y
int x, y;
scanf("%d%d", &x, &y);
if (a[x] < y && b[y] < x) {//如果新录入x有相同的y比之前大,重新赋值,y也一样
if (a[x] > 0)//x录入过相同的
b[a[x]] = 0;//对b数组对应a[x]对应值改为0,后续重新赋值
if (b[y] > 0)//y录入过相同的
a[b[y]] = 0;//对a数组对应b[y]对应值改为0,后续重新赋值
a[x] = y;//对x重新赋值
b[y] = x;//对y重新赋值
}
}
int ans = 0;//统计a和b数组为0的个数
for (int i = 1; i <= n; ++i) {
if (a[i] == 0)
++ans;
if (b[i] == 0)
++ans;
}
printf("%d", ans);
return 0;
}
1 当m>0时,输出的值一定小于2n。( )
2 执行完第27行的"++ans"时,ans —定是偶数。( )
3 a[i]和b[i]不可能同时大于0。( )
4 右程序执行到第13行时,x总是小于y,那么第15行不会被执行。( )
5 若m个x两两不同,且m个y两两不同,则输出的值为( )
A 2n-2m
B 2n+2
C 2n-2
D 2n
6 若m个x两两不同,且m个y都相等,则输出的值为( )
A 2n-2
B 2n
C 2m
D 2n-2m
根据问题分析关键程序:
仔细阅读题目描述,理解问题的核心要求。
将问题与程序代码对应起来,找出实现问题解决方案的关键部分。
重点关注这些关键部分的逻辑和变量变化。
此外,还有一些额外的模拟算法解题技巧:
细化模拟步骤:将复杂的程序逻辑分解为更小的步骤,逐步模拟每个步骤的执行过程和结果。
记录中间状态:在模拟过程中,记录所有相关变量的中间状态,以便于跟踪和调试。
验证模拟结果:在完成模拟后,使用题目给出的测试用例或自己设计的测试用例来验证模拟结果的正确性。
注意边界条件:特别关注程序处理边界输入或特殊情况的能力,这些往往是解题的关键所在。
通过综合运用这些技巧,选手可以更加高效地利用模拟算法解决信息学竞赛初赛中的难题
思路分析
1 当m>0时,输出的值一定小于2n。( T )
for (int i = 1; i <= n; ++i)
a[i] = b[i] = 0;
x和y都是在[1, n]的范围内的整数,说明x和y对应的数组的值赋值为0
for (int i = 1; i <= m; ++i) {
int x, y;
scanf("%d%d", &x, &y);
if (a[x] < y && b[y] < x) {
if (a[x] > 0)
b[a[x]] = 0;
if (b[y] > 0)
a[b[y]] = 0;
a[x] = y;
b[y] = x;
}
}
m>0 说明进入循环,并且a[x]=0 y>=1,a[y]=0 x>=1 必然存在a[x] = y;b[y] = x;
输出a数组和b数组为0的累加,如果都为0,累加和为2n,前面有不为0的,所以输出小于2n
2 执行完第27行的"++ans"时,ans —定是偶数。( F )
22 int ans = 0;
23 for (int i = 1; i <= n; ++i) {
24 if (a[i] == 0)
25 ++ans;
26 if (b[i] == 0)
27 ++ans;
28 }
27行是b数组为0的累加统计,在for循环中累加,当25没累加时,27执行完就是奇数,可以尝试找出反例
n=10,m=1,x=2,y=4时
a和b数组如下图,当i=2时,25行ans没累加,此时27行ans累加后为3,不是偶数
3 a[i]和b[i]不可能同时大于0。( F )
当输入的x和y相等时,a[i]和b[i]可能同时大于0
例如
n=10,m=1,x=2,y=2
a和b数组如下图,当i=2时,a[2]=2,b[2]=2
4 若程序执行到第13行时,x总是小于y,那么第15行不会被执行。( F )
当x不变,y增加时可以找出反例
n=10 m=2
x=1 y=2
a[1]=2 b[2]=1
x=1 y=3
此时满足13行 a[1]>0 执行15行b[a[x]]=b[2]=0 清空b[2]对应的a的下标,后面重新赋值新的下标
5 若m个x两两不同,且m个y两两不同,则输出的值为( A )
A 2n-2m
B 2n+2
C 2n-2
D 2n
m个x两两不同,且m个y两两不同,就会正常a中m个元素不为0,b中m个元素不为0
不为0的个数总共2*m个
数组a和b总共2n个元素
所以输出的ans为的元素为2*n-2*m
6 若m个x两两不同,且m个y都相等,则输出的值为( A )
A 2n-2
B 2n
C 2m
D 2n-2m
如果y都相等,第1次 x ,y对a和b数组赋值后,第2次由于y不变,所以b[y]不变,所以a[b[y]]会被清0,a数组重新赋值,b[y]对应的值更新
所以每次更改后,a和b数组分别只有1个不为0的数
例如
n=10 m=2
x=2 y=1
再输入一对x y后
x=3 y=1
由此可知,无论输入多少个这样的数,最后a和b数组中只有2个不为0的数
所以ans=2n-2