洛谷 B4063 [GESP202412 一级] 奇数和偶数
大家好呀!今天咱们要一起学习洛谷上的一道基础编程题 ——B4063 [GESP202412 一级] 奇数和偶数。这道题是 GESP 一级考试的真题,难度非常适合编程入门者,主要考察对 “奇数偶数判断” 和 “循环计数” 的基本掌握。哪怕你是刚接触编程的新手,跟着我一步步分析,也能轻松学会这道题的解法哦~定义变量naans1ans2(其中ans1和ans2初始为 0);读取n的值;循环n次:读取整数
洛谷 B4063 [GESP202412 一级] 奇数和偶数
点点关注(花花花)
恩师:hnjzsyjyj
一、题目介绍:初识奇数和偶数问题
大家好呀!今天咱们要一起学习洛谷上的一道基础编程题 ——B4063 [GESP202412 一级] 奇数和偶数。这道题是 GESP 一级考试的真题,难度非常适合编程入门者,主要考察对 “奇数偶数判断” 和 “循环计数” 的基本掌握。哪怕你是刚接触编程的新手,跟着我一步步分析,也能轻松学会这道题的解法哦~
1.1 题目来源与定位
洛谷 B4063 来自 2024 年 12 月的 GESP 一级考试,难度评级为 “入门”。它是编程初学者的经典练习题,主要考察三个核心知识点:
- 基本输入输出(读取数据、输出结果)
- 分支判断(if 语句判断奇偶数)
- 循环结构(while 循环处理多个数据)
- 计数器的使用(统计奇数和偶数的数量)
这道题虽然简单,但却是理解 “条件判断” 和 “循环统计” 的基础,学会它能为后续更复杂的编程题打下扎实的基础。
1.2 题目描述
咱们先来明确题目要求,用最通俗的话来讲:
题目需要我们写一个程序,完成以下操作:
- 首先输入一个整数
n,表示接下来有n个整数要处理; - 然后依次输入
n个整数; - 统计这
n个整数中,奇数有多少个,偶数有多少个; - 最后输出两个结果:第一个是奇数的数量,第二个是偶数的数量,中间用空格隔开。
什么是奇数和偶数呢?简单复习一下数学知识:
- 偶数:能被 2 整除的整数,比如 0、2、4、6、8……
- 奇数:不能被 2 整除的整数,比如 1、3、5、7、9……
- 判断方法:一个数除以 2 的余数如果是 1,就是奇数;余数是 0,就是偶数。
1.3 输入输出示例
为了更清楚理解题目,咱们看两个示例:
示例 1:
- 输入:
3(表示有 3 个整数) - 接着输入:
1 2 3 - 分析:1 是奇数,2 是偶数,3 是奇数
- 奇数数量:2,偶数数量:1
- 输出:
2 1
示例 2:
- 输入:
5 - 接着输入:
10 15 0 7 22 - 分析:10(偶)、15(奇)、0(偶)、7(奇)、22(偶)
- 奇数数量:2,偶数数量:3
- 输出:
2 3
通过示例可以看出,0 是偶数哦!这一点初学者容易忽略,要特别注意~
1.4 题目难度与适合人群
这道题是 GESP 一级的题目,难度非常基础,适合以下人群:
- 刚接触 C++ 编程的初学者(学习时间 1-2 个月)
- 已经掌握变量定义、输入输出、if 语句和循环的同学
- 想巩固 “条件判断” 和 “计数器” 用法的编程爱好者
如果你能看懂简单的if语句和while循环,这道题对你来说会很轻松。即使是纯新手,跟着我的思路一步步来,也能很快学会~
二、解题思路:三步搞定奇偶数统计
面对编程题,不要急着写代码,先理清思路最重要。解决 “奇数和偶数” 问题可以分三步:读取输入数据→判断每个数是奇数还是偶数→统计数量并输出。咱们详细分析每一步的逻辑~
2.1 第一步:明确需要的变量
编程的第一步是想清楚需要哪些 “容器” 来存储数据,也就是变量。这道题需要的变量有:
n:用来存储输入的整数总个数(比如示例 1 中的 3)a:临时存储每次输入的整数(比如 1、2、3)ans1:计数器,统计奇数的数量(初始值为 0)ans2:计数器,统计偶数的数量(初始值为 0)
这些变量就像我们的 “工具包”,n是任务清单,a是当前处理的物品,ans1和ans2是两个计数器,分别记录奇数和偶数的数量。
2.2 第二步:读取数据并循环处理
题目要求先输入n,再输入n个整数。这意味着:
- 先用
cin读取n的值; - 然后循环
n次,每次读取一个整数到a中; - 对每个
a进行判断:是奇数就给ans1加 1,是偶数就给ans2加 1。
循环就像工厂的流水线,n是产品总数,每个a是流水线上的产品,我们需要逐个检查并分类计数。
2.3 第三步:判断奇偶数的核心逻辑
判断一个数是奇数还是偶数的核心是看它除以 2 的余数:
- 如果
a % 2 != 0(余数不是 0),说明是奇数,ans1++ - 否则(余数是 0),说明是偶数,
ans2++
这里的%是取余运算符,a % 2就是计算a除以 2 的余数。比如:
3 % 2 = 1→1 != 0→奇数→ans1++4 % 2 = 0→0 == 0→偶数→ans2++0 % 2 = 0→偶数→ans2++(记住 0 是偶数哦!)
2.4 完整流程总结
把三步思路串起来,完整的流程就是:
- 定义变量
n、a、ans1、ans2(其中ans1和ans2初始为 0); - 读取
n的值; - 循环
n次:- 读取整数到
a; - 判断
a是奇数还是偶数; - 对应计数器加 1;
- 读取整数到
- 循环结束后,输出
ans1和ans2。
这个流程就像咱们整理水果:先知道有多少个水果(n),然后逐个检查每个水果是苹果还是香蕉(奇还是偶),分别放在两个篮子里(ans1和ans2),最后告诉别人每个篮子里有多少个水果。
三、代码解析:逐行读懂奇偶数统计的实现
根据上面的解题思路,用户提供的代码完美实现了所有功能。咱们逐行分析这段代码,看看它是如何一步步工作的:
cpp
#include<bits/stdc++.h>
using namespace std;
int n,a,ans1,ans2;
int main(){
cin>>n;
while(n--){
cin>>a;
if(a%2!=0)ans1++;
else ans2++;
}
cout<<ans1<<" "<<ans2;
return 0;
}
这段代码非常简短,但逻辑完整,咱们逐行拆解:
3.1 头文件与命名空间:代码的 “基础配置”
cpp
#include<bits/stdc++.h>
using namespace std;
这两行是 C++ 代码的标准开头,作用是:
#include<bits/stdc++.h>:引入 C++ 的 “万能头文件”,它包含了所有常用的标准库(比如输入输出、数学运算等),省去了我们逐个引入头文件的麻烦。对于初学者来说,记住这一行就够了,不用纠结具体包含了什么。using namespace std;:声明使用标准命名空间。C++ 的很多函数(比如cin、cout)都在std这个命名空间里,加上这句话,我们就可以直接写cin而不用写std::cin,简化代码。
这两行代码就像我们写作文时的 “纸和笔”,是基础工具,几乎所有 C++ 程序都会用到~
3.2 变量定义:准备 “工具包”
cpp
int n,a,ans1,ans2;
这行代码定义了 4 个整数变量,它们的作用在 2.1 节已经讲过:
n:存储整数的总个数a:临时存储当前输入的整数ans1:奇数计数器(初始值为 0,因为全局变量默认初始值为 0)ans2:偶数计数器(初始值为 0)
这里要注意:变量定义在main函数外面(全局变量),所以ans1和ans2会自动初始化为 0。如果定义在main函数内部,需要手动初始化(比如int ans1 = 0;),否则初始值是随机的,会导致统计错误!
3.3 主函数:程序的 “核心工厂”
main函数是程序的入口,所有操作都在这里执行,就像工厂的核心车间。咱们一步步看:
3.3.1 读取整数个数 n
cpp
cin>>n;
这行代码通过cin从输入设备(比如键盘)读取n的值。比如输入3,n就等于 3,告诉程序接下来要处理 3 个整数。
cin是 C++ 的输入函数,>>是输入运算符,作用是把输入的数据 “流” 到变量里。可以理解为 “把键盘输入的数放到n这个盒子里”。
3.3.2 循环处理 n 个整数
cpp
while(n--){
// 循环体:读取a并判断
}
这是一个while循环,作用是重复执行n次操作。n--是 “先判断后减 1” 的意思:
- 第一次循环时,判断
n是否大于 0(此时n是初始值,比如 3); - 执行循环体;
- 循环体结束后,
n的值减 1(3→2→1→0); - 当
n减到 0 时,循环结束(因为 0 表示假,循环停止)。
这个循环就像一个倒计时器,n是初始时间,每次循环后时间减 1,直到时间为 0,共执行n次循环。
3.3.3 读取当前整数 a
cpp
cin>>a;
在循环体内部,这行代码每次读取一个整数,存储到a中。比如第一次循环读取 1,a=1;第二次读取 2,a=2;第三次读取 3,a=3。
a就像一个 “临时托盘”,每次装一个整数,处理完后再装下一个。
3.3.4 判断奇偶数并计数
cpp
if(a%2!=0)ans1++;
else ans2++;
这是整个程序的核心判断逻辑,用if-else语句实现:
a%2:计算a除以 2 的余数(比如3%2=1,4%2=0);a%2!=0:如果余数不等于 0(即余数是 1),说明是奇数,执行ans1++(ans1的值加 1);else:否则(余数是 0),说明是偶数,执行ans2++(ans2的值加 1)。
举个例子,当a=1时:
1%2=1,1!=0为真,所以ans1从 0 变成 1;
当a=2时:2%2=0,0!=0为假,执行else,ans2从 0 变成 1;
当a=3时:3%2=1,ans1从 1 变成 2。
这样循环结束后,ans1=2(奇数个数),ans2=1(偶数个数),和示例 1 的结果一致~
3.3.5 输出结果
cpp
cout<<ans1<<" "<<ans2;
循环结束后,ans1和ans2分别存储了奇数和偶数的数量。这行代码通过cout输出两个结果:
- 第一个是
ans1(奇数数量); - 中间用空格隔开(
" "); - 第二个是
ans2(偶数数量)。
cout是 C++ 的输出函数,<<是输出运算符,作用是把变量的值 “流” 到屏幕上。比如ans1=2,ans2=1,就会在屏幕上输出2 1。
3.3.6 程序结束
cpp
return 0;
表示main函数执行完毕,程序正常退出。这行代码是 C++ 程序的规范结尾,告诉操作系统程序成功运行结束。
3.4 完整代码执行流程
为了让大家更清晰理解,咱们用示例 1(输入3 1 2 3)完整演示程序的执行过程:
- 初始状态:
n未赋值,a未赋值,ans1=0,ans2=0; - 读取 n:
cin>>n后,n=3; - 第一次循环(n=3→2):
cin>>a读取 1,a=1;a%2=1,1!=0为真,ans1++→ans1=1;
- 第二次循环(n=2→1):
cin>>a读取 2,a=2;a%2=0,0!=0为假,ans2++→ans2=1;
- 第三次循环(n=1→0):
cin>>a读取 3,a=3;a%2=1,1!=0为真,ans1++→ans1=2;
- 循环结束(n=0):
- 执行
cout<<ans1<<" "<<ans2,输出2 1;
- 执行
- 程序结束:
return 0。
整个过程就像流水线作业,每个数都被正确判断并计数,最终输出结果。
四、核心知识点详解:搞懂每个关键概念
这道题虽然简单,但包含了几个重要的编程基础知识点,咱们逐个详解,帮你彻底理解~
4.1 变量定义与初始化
变量是编程的基础,就像我们生活中的盒子,用来装数据。在 C++ 中定义变量的格式是:数据类型 变量名;。
这道题用的是int类型(整数类型),可以存储正整数、负整数和 0。定义多个变量时,用逗号隔开:int n,a,ans1,ans2;。
初始化是给变量赋初始值。全局变量(定义在main外)会自动初始化为 0,而局部变量(定义在main内)需要手动初始化,比如:
cpp
int main(){
int ans1 = 0; // 必须手动初始化
int ans2 = 0;
// ...其他代码
}
如果局部变量不初始化,它的值是随机的(比如之前内存中的残留值),会导致统计错误!这是初学者最容易踩的坑之一,一定要注意~
4.2 输入输出:程序与用户的交互
程序需要和用户交互,cin和cout就是交互的工具:
cin>>变量名:从输入设备(键盘)读取数据到变量;cout<<变量名:把变量的值输出到屏幕。
使用时要注意:
- 读取多个数据时,
cin可以连写:cin>>n>>a(但这道题需要先读 n,再循环读 a); - 输出多个内容时,
cout可以连写,用<<连接:cout<<ans1<<" "<<ans2; - 输出空格时,用
" "表示(双引号包裹空格)。
输入输出就像程序的 “嘴巴和耳朵”,让程序能接收指令并展示结果。
4.3 循环结构:重复执行的利器
这道题用了while(n--)循环,它的作用是重复执行n次操作。while循环的基本格式是:
cpp
while(条件){
// 循环体:要重复执行的代码
}
当条件为真(非 0)时,执行循环体;执行完后再次判断条件,直到条件为假(0)时停止。
n--是 “后置递减”,先使用n的当前值判断条件,再把n减 1。比如n=3时:
for(int i=0;i<n;i++){
cin>>a;
if(a%2!=0)ans1++;
else ans2++;
}
4.4 分支判断:if-else 语句
判断奇偶数的核心是if-else语句,它的作用是 “根据条件选择不同的操作”,基本格式是:
if(条件){
// 条件为真时执行的代码
}else{
// 条件为假时执行的代码
}
4.5 计数器:累加统计
计数器是统计类问题的核心工具,ans1和ans2就是两个计数器。计数器的使用步骤是:
五、易错点分析:避开这些 “坑”
虽然这道题简单,但初学者很容易在细节上出错。咱们盘点几个常见的易错点,帮你避开陷阱~
5.1 变量未初始化
错误示例:
int main(){
int n,a,ans1,ans2; // 错误:局部变量未初始化
cin>>n;
while(n--){
cin>>a;
if(a%2!=0)ans1++;
else ans2++;
}
cout<<ans1<<" "<<ans2;
}
int ans1 = 0, ans2 = 0; // 正确:手动初始化为0
5.2 奇偶数判断条件错误
错误示例:
if(a%2==1)ans1++; // 错误:忽略了负奇数的情况
else ans2++;
if(a%2!=0)ans1++; // 正确:所有奇数都满足
else ans2++;
5.3 循环次数错误
错误示例:
while(n){ // 错误:循环条件应为n--
cin>>a;
// ...判断代码
n--;
}
5.4 输出格式错误
错误示例 1:输出时忘记加空格
cout<<ans1<<ans2; // 错误:输出结果连在一起,如“21”
cout<<"奇数:"<<ans1<<" 偶数:"<<ans2; // 错误:包含多余文字
cout<<ans1<<" "<<ans2; // 正确格式
5.5 数据类型选择错误
虽然这道题的输入范围不会导致问题,但初学者可能会疑惑:为什么用int类型?int类型能存储的整数范围是 - 2147483648 到 2147483647,足够存储题目中的输入数据(GESP 一级题的输入通常在这个范围内)。如果遇到更大的数,可能需要用long long类型,但这道题用int完全足够。
六、代码优化与拓展:让程序更完善
这道题的代码虽然简单,但可以通过一些优化让它更规范、更高效。同时,我们也可以拓展思路,解决更复杂的问题~
6.1 变量命名更清晰
示例代码用ans1和ans2作为计数器,虽然简洁,但可以起更有意义的名字,让代码更容易理解:
int odd_count = 0; // 奇数计数器(odd表示奇数)
int even_count = 0; // 偶数计数器(even表示偶数)
6.2 用 for 循环替代 while 循环
除了while(n--),也可以用for循环处理,逻辑更清晰:
cin>>n;
for(int i=0;i<n;i++){ // i从0到n-1,共循环n次
cin>>a;
if(a%2!=0)odd_count++;
else even_count++;
}
6.3 处理负数的特殊情况
题目中没有明确说明输入是否包含负数,但好的程序应该能处理负数。如 4.5 节所述,用a%2!=0判断奇数可以正确处理负数,比如:
6.4 拓展练习:计算奇偶数的和
学会了统计奇偶数的数量,我们可以尝试更复杂的问题:计算所有奇数的和与所有偶数的和。
#include<bits/stdc++.h>
using namespace std;
int n,a,sum_odd,sum_even; // 累加器
int main(){
cin>>n;
while(n--){
cin>>a;
if(a%2!=0)sum_odd += a; // 奇数累加
else sum_even += a; // 偶数累加
}
cout<<sum_odd<<" "<<sum_even;
return 0;
}
六、PPT 展示建议:让讲解更清晰
如果用这篇内容制作 PPT,建议按以下结构分页,突出重点,适合课堂讲解或自我复习:
七、写在最后:从简单题中积累编程思维
“奇数和偶数” 这道题虽然简单,但蕴含了编程的核心思维:把复杂问题拆解为简单步骤,用变量存储数据,用循环处理重复操作,用判断实现分支逻辑,用计数器统计结果。这些思维不仅适用于这道题,更适用于未来更复杂的编程问题。
- 第一次判断:条件是 3(真),执行循环体,然后 n 变成 2;
- 第二次判断:条件是 2(真),执行循环体,然后 n 变成 1;
- 第三次判断:条件是 1(真),执行循环体,然后 n 变成 0;
- 第四次判断:条件是 0(假),循环结束。
- 如果条件为真(余数是 1),说明是奇数,执行
ans1++; - 如果条件为假(余数是 0),说明是偶数,执行
ans2++。 - 初始化计数器为 0;
- 每次遇到符合条件的数据,计数器加 1(
ans++); - 所有数据处理完后,计数器的值就是统计结果。
-3%2 = -1→-1 != 0→奇数,正确;-4%2 = 0→偶数,正确。- 奇数和:1+3=4
- 偶数和:2
- 输出:
4 2 -
封面页:
- 标题:洛谷 B4063 奇数和偶数
- 副标题:GESP 一级编程题解析
- 背景图:数字或代码相关图片(如 0 和 1 组成的背景)
-
题目介绍页:
- 用简洁语言描述题目要求(输入 n 个整数,统计奇偶数数量)
- 列出输入输出格式(表格形式)
- 展示 1-2 个示例(输入→分析→输出)
-
核心思路页:
- 用流程图展示 “读取 n→循环读 a→判断奇偶数→统计计数→输出结果” 的步骤
- 标注每个步骤的作用,用箭头连接流程
-
奇偶数判断原理页:
- 简单复习奇偶数的数学定义
- 重点讲解判断方法:
a%2!=0是奇数,否则是偶数 - 举例说明(3 是奇数,4 是偶数,0 是偶数)
-
代码框架页:
- 展示完整代码,用不同颜色标出核心部分(变量定义、循环、判断、输出)
- 简要说明代码结构:输入→循环→判断→输出
-
代码解析页(分 2-3 页):
- 逐行解释代码含义,重点讲解变量作用
- 单独讲解 while 循环的执行过程(用 n=3 举例)
- 单独讲解 if-else 判断逻辑(用 a=1、a=2 举例)
-
执行过程演示页:
- 以示例输入为例,用表格展示每一步的变量变化:
循环次数 n 的值 a 的值 ans1 ans2 初始 3 无 0 0 第一次 3→2 1 1 0 第二次 2→1 2 1 1 第三次 1→0 3 2 1 - 用动画或颜色标注变化过程
- 以示例输入为例,用表格展示每一步的变量变化:
-
易错点分析页:
- 用 “错误代码 + 正确代码” 的对比表格,列出常见错误:
错误类型 错误代码示例 正确代码示例 变量未初始化 int ans1; int ans1 = 0; 判断条件错误 if(a%2==1) if(a%2!=0) 输出格式错误 cout<<ans1<<ans2; cout<<ans1<<" "<<ans2; - 标注错误原因和后果
- 用 “错误代码 + 正确代码” 的对比表格,列出常见错误:
-
核心知识点总结页:
- 用 bullet point 列出关键知识点:
- 变量定义与初始化的重要性
- while 循环的使用(控制循环次数)
- if-else 分支判断(奇偶数判断)
- 计数器的累加统计方法
- 输入输出格式规范
- 用 bullet point 列出关键知识点:
-
拓展练习页:
- 提出拓展问题(如计算奇偶数的和)
- 展示拓展题的思路和代码框架
- 鼓励尝试并对比与本题的异同
更多推荐



所有评论(0)