模拟法
模拟法
理解模拟算法的原理及特点,可以解决实际问题。
官方详述(8)原文:理解模拟算法、模拟算法的原理及特点。模拟法按题目给出的规则,把现实过程一步步在程序里复现:时间推进、状态更新、人物或棋子移动,都是「照着做」而不是另找公式。原理是状态与规则一一对应;特点是实现贴近题意、正确性依赖边界是否写全,而不是依赖最优子结构。规模小时直接模拟即可;步骤太多时再考虑是否存在周期或可合并的更新,但三级编程以能完整走完过程为主。
客观题常给一段按日、按轮更新的代码,问若干步之后某个变量的值。编程题则把规则写成自然语言,要求输出结束状态——日历推进、队列轮转、按条件改写数组,都是典型模拟。认证标准规定考试时长为 120 分钟,写模拟前先列出「有哪些变量、每一步改谁」,再开循环,避免漏掉最后一轮。
// 模拟:从 start 起连续 d 天,每天温度加 delta,统计有几天超过 limit
int t = start, days = 0;
for (int i = 0; i < d; ++i) {
if (t > limit) ++days;
t += delta;
}
循环条件、最后一天是否还更新、并列规则谁先谁后,都必须与题面顺序一致。
在下列代码的输出是( )。

#include <iostream>
using namespace std;
int main() {
int array[10];
for (int i = 0; i < 10; i++)
array[i] = i;
for (int p = 2; p < 10; p++)
if (array[p] == p)
for (int n = p; n < 10; n += p)
array[n] = array[n] / p * (p - 1);
int res = 0;
for (int n = 1; n < 10; n++)
res += array[n];
cout << res << endl;
return 0;
}
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写措辞改写题干
原卷作
在下列代码的输出是,常规写法应为下列代码的输出是洛谷有题写成「下列代码的输出是」且代码围栏未闭合;官方 PDF 第 4 页题干为「在下列代码的输出是」,程序为嵌入位图 fig-04.png(宽 560),已按页面恢复。
已按官方原件恢复:现为原卷原文
执行下面C++代码输出是()。
int temp=0;
for(int i=1;i<7;i++)
{
for(int j=1;j<5;j++)
{
if(i/j==2)
{
temp++;
}
}
}
cout<<temp<<endl;
下面 C++ 程序执行的结果是()。
int cnt=0;
for(int i=0;i<=20;i++)
{
if(i%3==0&&i%5==0)
{
cnt++;
}
}
cout<<cnt;
C++ 代码用于抽取字符串中的电话号码。约定:电话号码全部是数字,数字之间没有其他符号如连字符或空格等。代码中变量 strSrc 仅仅是示例,可以包含更多字符。下面有关代码说法,正确的说法是()。
string strSrc="红十字: 01084025890火警电话: 119急救电话: 120紧急求助: 110";
string tel="";
for(int i=0;i<=strSrc.length();i++)
{
if(strSrc[i]>='0'&&strSrc[i]<='9')
{
tel=tel+strSrc[i];
}
else if(tel!="")
{
cout<<tel<<endl;
tel="";
}
}
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写标点题干
原卷作
红十字: 01084025890火警电话: 119急救电话: 120紧急求助: 110,常规写法应为红十字:01084025890火警电话:119急救电话:120紧急求助:110洛谷有题把原卷嵌入截图里的 ASCII 冒号+空格改成全角冒号且去掉空格;已按官方 PDF 第 4 页代码截图恢复。
已按官方原件恢复:现为原卷原文
单位转换
C++时间 1 s内存 512 MB标准输入输出
小杨这周的数学作业是做单位转换,喜欢编程的小杨决定编程帮他解决这些问题。
小杨只学了长度单位和重量单位,具体来说:
长度单位包括千米(
km)、米(m)、毫米(mm),它们之间的关系是:1km=1000m=1000000mm。重量单位包括千克(
kg)、克(g)、毫克(mg),它们之间的关系是:1kg=1000g=1000000mg。
小杨的作业只涉及将更大的单位转换为更小的单位,也就是说,小杨的作业只会包含如下题型:米转换为毫米,千米转换为毫米,千米转换为米,克转换为毫克,千克转换为毫克,千克转换为克。
现在,请你帮忙完成单位转换的程序。
输入格式
输入的第一行为一个整数,表示题目数量。
接下来 N 行,每行一个字符串,表示转换单位的题目,格式为 x 单位 1=? 单位 2。其中,x 为一个不超过 1000 的非负整数, 单位 1 和 单位 2 分别为两个单位的英文缩写,保证它们都是长度单位或都是重量单位,且 单位 1 比 单位 2 更大。
例如,如果题目需要你将 1km 转换为 mm,则输入为 1 km = ? mm。
保证 1≤N≤1000。
输出格式
输出 N 行,依次输出所有题目的答案,输出时,只需要将输入中的 ? 代入答案,其余部分一字不差地输出即可。由于小杨的题目只涉及将更大的单位转换为更小的单位,并且输入的 x 是整数,因此答案一定也是整数。
例如,如果题目需要你将 1km 转换为 mm,则输入为 1 km = ? mm。则你需要输出 1 km = 1000000 mm。
样例
2 1 km = ? mm 1 m = ? mm
1 km = 1000000 mm 1 m = 1000 mm
5 100 m = ? mm 1000 km = ? m 20 kg = ? g 200 g = ? mg 0 kg = ? mg
100 m = 100000 mm 1000 km = 1000000 m 20 kg = 20000 g 200 g = 200000 mg 0 kg = 0 mg
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
执行下面 C++ 代码后输出的第一个数是( )。
int main()
{
int a[20],i;
for(i = 0; i < 20; i++)
a[i] = i+1;
for( ; i > 0; i--)
cout << a[i-1] << " ";
cout << endl;
return 0;
}
假设英文句子由若干词构成。下面 C++ 代码统计输出的词数是( )。
int main()
{
string str="gEsP is Interesting !";
int x = str.length();
int nwords = 0;
for(int i = 0; i < x; i++)
if (str[i]==' '){
nwords++;
while(str[++i]==' ') ;
}
cout << nwords << endl;
cout << endl;
return 0;
}
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写数值印错题干
原卷作
string str="gEsP is Interesting !";,常规写法应为string str = "gEsP is Interesting !";洛谷把原卷字符串里 Interesting 两侧的双空格压成单空格;已按官方 PDF 第 3–4 页列位恢复。
已按官方原件恢复:现为原卷原文
下面 C++ 程序执行的结果是( )。
int main()
{
int a[20],i;
int cnt=0;
for(i = 0; i < 20; i++)
a[i] = i+1;
for( ; i > 1; i--)
if((a[i-1]+a[i-2])%3)
cnt++;
cout << cnt << endl;
cout << endl;
return 0;
}
执行下面 C++ 代码后,输出的结果不可能是 89781。
#include <iostream>
#include <cstdlib> // 为了使用 rand() 和 srand()
#include <ctime> // 为了使用 time()
using namespace std;
int main() {
// 设置随机种子
srand(time(NULL));
int i = 1;
int s[5];
while(i <= 5)
{
int a = rand() % 10;
if(a % 3 == (i + 1) % 3)
s[i++] = a;
}
for(int i = 1; i <= 5; i++)
cout << s[i];
cout << endl;
return 0;
}
移位
C++时间 1 s内存 512 MB标准输入输出
小杨学习了加密技术移位,所有大写字母都向后按照一个固定数目进行偏移。偏移过程会将字母表视作首尾相接的环,例如,当偏移量是 3 的时候,大写字母 A 会替换成 D,大写字母 Z 会替换成 C,总体来看,大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 会被替换成 DEFGHIJKLMNOPQRSTUVWXYZABC。
注:当偏移量是 26 的倍数时,每个大写字母经过偏移后会恰好回到原来的位置,即大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 经过偏移后会保持不变。
输入格式
第一行包含一个正整数 n。
输出格式
输出在偏移量为 n 的情况下,大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 移位替换后的结果。
样例
3
DEFGHIJKLMNOPQRSTUVWXYZABC
【样例解释】
当偏移量是 3 的时候,大写字母 A 会替换成 D,大写字母 Z 会替换成 C,总体来看,大写字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ 会被替换成 DEFGHIJKLMNOPQRSTUVWXYZABC。
数据范围
对于全部数据,保证有 1≤n≤100。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
陈A歹种植一批农作物,第一天需要浇水一次,随后的两天(第 2、第 3 天),每天需要浇水 2 次,再随后的 3 天(第 4、第 5、第 6 天),需要每天浇水 3 次,这样持续下去,随后的 n 天,每天需要浇水 n 次。请问在 100 天里,总共浇了多少次水( )
打印数字
C++时间 1 s内存 512 MB标准输入输出
小杨为数字 0,1,2 和 3 设计了一款表示形式,每个数字占用了 5×5 的网格。数字 0,1,2 和 3 的表示形式如下:
..... ****. ..... .....
.***. ****. ****. ****.
.***. ****. ..... .....
.***. ****. .**** ****.
..... ****. ..... .....
小杨想请你将给定的数字 n 转换为对应的表示形式。
输入格式
第一行包含一个非负整数代表 n。
输出格式
输出对应的表示形式。
样例
12230
****..................... ****.****.****.****..***. ****.................***. ****..****.********..***. ****.....................
数据范围
对于全部数据,保证有 0≤n≤106,且 n 仅由数字 0,1,2,3 组成。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
Base64 编码将每 3 字节的输入数据编码为 4 字节的输出数据。如果输入数据长度不是 3 的倍数,会用 = 号填充。在 Base64 编码中,如果输入字符串的长度为 10 字节,编码后的字符串长度是多少( )
以下程序模拟了一个简单的小球反弹过程,横线处应该填入的是( )
#include <iostream>
using namespace std;
int main() {
int height = 10;
int distance = 0;
for (int i = 1; i <= 5; i++) { // 模拟5次落地
________________
height /= 2;
distance += height;
}
cout << distance << endl;
return 0;
}
执行以下 C++ 代码后,c 的数值是( )。
int a = 10, b = 3;
double c = a / b;
执行以下 C++ 代码后,变量 sum 的值是( )。
int sum = 0;
for (int i = 1; i <= 5; i += 2) {
sum += i;
int sum=0;
}
以下 C++ 代码 count++ 执行的次数是( )。
int i = 10;
int count=0;
while (i > 0) {
i -= 3;
continue;
count++;
}
以下 C++ 代码段的输出是( )。
for (int i = 0; i < 4; i++) {
for (int j = 0; j <= i; j++) {
cout << j;
}
cout << "#";
}
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写错字选项 4
原卷作
0#01#012#01243#洛谷有题选项 D 多写一个 3(0#01#012#012343#);官方 PDF 第 2 页文本层与整页图像均为 0#01#012#01243#,已恢复。
已按官方原件恢复:现为原卷原文
do { ... } while (false); 循环体内的语句至少会被执行一次。
数组清零
C++时间 1 s内存 512 MB标准输入输出
小 A 有一个由 n 个非负整数构成的数组 a=[a1,a2,…,an]。他会对数组 a 重复进行以下操作,直到数组 a 只包含 0。在一次操作中,小 A 会依次完成以下三个步骤:
- 在数组 a 中找到最大的整数,记其下标为 k。如果有多个最大值,那么选择其中下标最大的。
- 从数组 a 所有不为零的整数中找到最小的整数 aj。
- 将第一步找出的 ak 减去 aj。
例如,数组 a=[2,3,4] 需要 7 次操作变成 [0,0,0]:
[2,3,4]→[2,3,2]→[2,1,2]→[2,1,1]→[1,1,1]→[1,1,0]→[1,0,0]→[0,0,0]小 A 想知道,对于给定的数组 a,需要多少次操作才能使得 a 中的整数全部变成 0。可以证明,a 中整数必然可以在有限次操作后全部变成 0。你能帮他计算出答案吗?
输入格式
第一行,一个正整数 n,表示数组 a 的长度。
第二行,n 个非负整数 a1,a2,…,an,表示数组 a 中的整数。
输出格式
一行,一个正整数,表示 a 中整数全部变成 0 所需要的操作次数。
样例
3 2 3 4
7
5 1 3 2 2 5
13
数据范围
对于所有测试点,保证 1≤n≤100,0≤ai≤100。
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写错字题面描述
原卷作
他会对数组 $a$ 重复进行以下操作洛谷 B4413 题面作「阵组」;官方 PDF 第 5 页作「数组」,已恢复。其余题面/样例仍以洛谷为准。
已按官方原件恢复:现为原卷原文
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
日历制作
C++时间 1 s内存 512 MB标准输入输出
小 A 想制作 2025 年每个月的日历。他希望你能编写一个程序,按照格式输出给定月份的日历。
具体来说,第一行需要输出 MON TUE WED THU FRI SAT SUN,分别表示星期一到星期日。接下来若干行中依次输出这个月所包含的日期,日期的个位需要和对应星期几的缩写最后一个字母对齐。例如,2025 年 9 月 1 日是星期一,在输出九月的日历时,1 号的个位 1 就需要与星期一 MON 的最后一个字母 N 对齐。九月的日历输出效果如下:
MON TUE WED THU FRI SAT SUN
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
你能帮助小 A 完成日历的制作吗?
输入格式
一行,一个正整数 m,表示需要按照格式输出 2025 年 m 月的日历。
输出格式
输出包含若干行,表示 2025 年 m 月的日历。
样例
9
MON TUE WED THU FRI SAT SUN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
6
MON TUE WED THU FRI SAT SUN
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
数据范围
对于所有测试点,保证 1≤m≤12。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
整型变量 x 的初始值为 10,以下代码的输出结果是( )
int t = x--;
t -= x;
cout << t << endl;
整型变量 a 的值为 3,浮点数变量 b 的值为 3.5,在 C++ 编译环境下,经过 a *= b 计算后,a 的值变为 10.5。此时如果输出 a,将输出 10.5。
以下代码输出结果为 8。
int a = 5, b = 3;
int c = a++ + ++b;
cout << c << endl;
以下代码中,Hello 将被输出 5 次。
for (int i = 0; i < 5; i++);
{
cout << "Hello" << endl;
}
模拟“字符串加密”:规则为“每个字符 ASCII 码 +3 ,若超过 z(122)则从 a 重新开始”,以下代码中正确的条件判断是:( )
for (int i = 0; i < str.length(); i++) {
// 需补充条件:
_______________________
else {
str[i] += 3;
}
}
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写版式题干
原卷作
// 需补充条件:,常规写法应为// 需补充条件:洛谷把填空行写成 16 个下划线、注释冒号为半角;官方 PDF 第 4 页为全角冒号与 23 个下划线。已按列位重建恢复。
已按官方原件恢复:现为原卷原文
凯撒密码
C++时间 1 s内存 512 MB标准输入输出
凯撒密码是一种替换加密技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是 3 的时候,所有的字母 A 将被替换成 D,B 被替换成 E,C 被替换成 F,以此类推,W 被替换成 Z,X 被替换成 A,Y 被替换成 B,Z 被替换成 C。这个加密方法是以罗马共和时期凯撒的名字命名的,据称当年凯撒曾用此方法与其将军们进行联系。
但是和所有的利用字母表进行替换的加密技术一样,凯撒密码非常容易被破解,而且在实际应用中也无法保证通信安全。
现在给你一个已破解的凯撒密码明文与密文,与一个有相同偏移量的未破解凯撒密码密文,请你帮忙破解它。
输入格式
输入共三行:
第一行包含一个字符串,表示已破解的凯撒密码明文;
第二行包含一个字符串,表示已破解的凯撒密码密文;
第三行包含一个字符串,表示待破解的凯撒密码密文。
输出格式
输出一行,包含一个字符串,表示待破解的凯撒密码对应的明文。
样例
ABCDEFGVWXYZ DEFGHIJYZABC WKHTXLFNEURZQIRAMXPSVRYHUWKHODCBGRJ
THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG
样例 1 中,通过已破解的密码得出偏移量为 'D' - 'A' = 3,因此,对未破解部分进行逆向偏移:密文中的 W 对应明文中的 T('W' - 3 = 'T'),密文中的 K 对应明文中的 H('K' - 3 = 'H'),以此类推。
数据范围
保证密码长度均不超过 1000,所有字符串由大写字母组成。
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写措辞改写输入格式
原卷作
表示已破解的凯撒密码密文,常规写法应为表示已破解的凯撒密码密文洛谷 B4500 把输入第二行写成「有相同偏移量的未破解凯撒密码密文」;官方 PDF 第 8 页为「已破解的凯撒密码密文」。争议回查后按原件恢复。题面其余仍以洛谷为准。
已按官方原件恢复:现为原卷原文
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
一种加密方式是字符数组与密钥 KEY、运算方式分开传输,比如字符数组 char text[4] = {'G', 'E', 'S', 'P'}; 由一种传输方式发送,密钥 KEY = 2026 通过另一种发送方式发送,运算方式 char function[4] = {'|', '-', '^', '+'}; 又是另一种发送方式发送。三种数据都到达目的地以后,分别进行例如 'G' | 6、'E' - 2、'S' ^ 0、'P' + 2 等计算,来得到相应的真实内容,上述 GESP 通过这种加密方式,加密以后最终的内容是( )。
代码逐行复刻手工运算步骤,中间不能增加任何判断逻辑,否则就不属于模拟算法。