枚举法与模拟法
枚举法与模拟法
枚举法;模拟法。
概念
枚举法在规模可控时,按规则遍历所有候选答案,逐一检验是否满足条件;模拟法则按题意逐步复现过程(时间推进、状态转移、规则更新),直接得到结果。二者常一起出现:模拟的每一步可能内嵌小范围枚举。与贪心、DP 不同,枚举/模拟不依赖「局部最优」或「最优子结构」,关键是边界清楚、状态更新无遗漏。与 cspj.algo.sorting(有序化)区分:排序是预处理或核心操作,而模拟/枚举的核心是「按规则走一遍或试一遍」。CSP-J 初赛阅读/完善程序里,模拟多体现为多重循环与变量同步更新;复赛编程题则常要处理大 n 时的优化或找规律。
CSP-J 常考
cspj-r1-2020第 20–27 题:阅读/完善程序段,按规则逐次更新变量或统计结果,典型模拟框架。cspj-r1-2023第 16、19–20 题:单选与阅读程序,考查按步模拟后数组或计数器的形态。cspj-r2-2019第 2 题:复赛编程,按时间序模拟地铁发券与公交核销规则。cspj-r2-2021第 4 题:复赛编程,小熊的果篮,每轮同时取各块最左水果并按规则模拟块合并。cspj-r2-2025第 2 题:复赛编程,按蛇形座位规则模拟排名与坐标映射。
// 模拟:掷骰子直到和为 7,统计投掷次数
int rolls = 0, sum = 0;
while (sum != 7) {
sum = rand() % 6 + 1 + rand() % 6 + 1;
++rolls;
}
// 枚举:找 1..n 中各位数字之和等于 k 的数
for (int x = 1; x <= n; ++x) {
int t = x, s = 0;
while (t) { s += t % 10; t /= 10; }
if (s == k) cout << x << ' ';
}
易错点
- 模拟题漏掉边界:循环条件用
<还是<=、最后一轮是否还要更新状态,阅读程序里改一个符号答案就变。 - 枚举范围缩太小:只枚举「看起来合理」的解而漏掉极端情况;完善程序空位若填循环上界,要对照题意里的取值范围。
- 大 n 仍写 O(n²) 真模拟:复赛要先判断能否找不变量、环或公式,否则只能拿部分分。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 √,错误填 ×
#include <cstdio>2using namespace std;3int n, m;4int a[100], b[100];56int main() {7 scanf("%d%d", &n, &m);8 for (int i = 1; i <= n; ++i)9 a[i] = b[i] = 0;10 for (int i = 1; i <= m; ++i) {11 int x, y;12 scanf("%d%d", &x, &y);13 if (a[x] < y && b[y] < x) {14 if (a[x] > 0)15 b[a[x]] = 0;16 if (b[y] > 0)17 a[b[y]] = 0;18 a[x] = y;19 b[y] = x;20 }21 }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 }29 printf("%d\n", ans);30 return 0;31}原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写其它程序 · 第 29 行
原卷作
printf("%d\n", ans);,常规写法应为printf("%d\n", ans);洛谷抓取件为 printf("%d", ans);;pages/pg-04.png 第 29 行含换行,已恢复。
已按官方原件恢复:现为原卷原文
- 22判断1.5 分
当 m>0 时,输出的值一定小于 2n。()
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 √,错误填 ×
#include <cstdio>2using namespace std;3int n, m;4int a[100], b[100];56int main() {7 scanf("%d%d", &n, &m);8 for (int i = 1; i <= n; ++i)9 a[i] = b[i] = 0;10 for (int i = 1; i <= m; ++i) {11 int x, y;12 scanf("%d%d", &x, &y);13 if (a[x] < y && b[y] < x) {14 if (a[x] > 0)15 b[a[x]] = 0;16 if (b[y] > 0)17 a[b[y]] = 0;18 a[x] = y;19 b[y] = x;20 }21 }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 }29 printf("%d\n", ans);30 return 0;31}原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写其它程序 · 第 29 行
原卷作
printf("%d\n", ans);,常规写法应为printf("%d\n", ans);洛谷抓取件为 printf("%d", ans);;pages/pg-04.png 第 29 行含换行,已恢复。
已按官方原件恢复:现为原卷原文
- 23判断1.5 分
执行完第 27 行的
++ans时,ans 一定是偶数。()原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写错字题干
原卷作
一定是偶数,常规写法应为一定是偶数洛谷抓取件为「—定是偶数」;pages/pg-04.png 为「一定是偶数」,已恢复。
已按官方原件恢复:现为原卷原文
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <cstdio>2using namespace std;3int n, m;4int a[100], b[100];56int main() {7 scanf("%d%d", &n, &m);8 for (int i = 1; i <= n; ++i)9 a[i] = b[i] = 0;10 for (int i = 1; i <= m; ++i) {11 int x, y;12 scanf("%d%d", &x, &y);13 if (a[x] < y && b[y] < x) {14 if (a[x] > 0)15 b[a[x]] = 0;16 if (b[y] > 0)17 a[b[y]] = 0;18 a[x] = y;19 b[y] = x;20 }21 }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 }29 printf("%d\n", ans);30 return 0;31}原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写其它程序 · 第 29 行
原卷作
printf("%d\n", ans);,常规写法应为printf("%d\n", ans);洛谷抓取件为 printf("%d", ans);;pages/pg-04.png 第 29 行含换行,已恢复。
已按官方原件恢复:现为原卷原文
- 26单选3 分
若 m 个 x 两两不同,且 m 个 y 两两不同,则输出的值为()
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <cstdio>2using namespace std;3int n, m;4int a[100], b[100];56int main() {7 scanf("%d%d", &n, &m);8 for (int i = 1; i <= n; ++i)9 a[i] = b[i] = 0;10 for (int i = 1; i <= m; ++i) {11 int x, y;12 scanf("%d%d", &x, &y);13 if (a[x] < y && b[y] < x) {14 if (a[x] > 0)15 b[a[x]] = 0;16 if (b[y] > 0)17 a[b[y]] = 0;18 a[x] = y;19 b[y] = x;20 }21 }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 }29 printf("%d\n", ans);30 return 0;31}原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写其它程序 · 第 29 行
原卷作
printf("%d\n", ans);,常规写法应为printf("%d\n", ans);洛谷抓取件为 printf("%d", ans);;pages/pg-04.png 第 29 行含换行,已恢复。
已按官方原件恢复:现为原卷原文
- 27单选3 分
若 m 个 x 两两不同,且 m 个 y 都相等,则输出的值为()
公交换乘
C++时间 1 s内存 256 MB 文件 IO:transfer.in → transfer.out
著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案:
- 在搭乘一次地铁后可以获得一张优惠票,有效期为 45 分钟,在有效期内可以消耗这张优惠票,免费搭乘一次票价不超过地铁票价的公交车。在有效期内指开始乘公交车的时间与开始乘地铁的时间之差小于等于 45 分钟,即:
tbus−tsubway≤45。 - 搭乘地铁获得的优惠票可以累积,即可以连续搭乘若干次地铁后再连续使用优惠票搭乘公交车。
- 搭乘公交车时,如果可以使用优惠票一定会使用优惠票;如果有多张优惠票满足条件,则优先消耗获得最早的优惠票。
现在你得到了小轩最近的公共交通出行记录,你能帮他算算他的花费吗?
输入格式
输入文件的第一行包含一个正整数 n,代表乘车记录的数量。
接下来的 n 行,每行包含 3 个整数,相邻两数之间以一个空格分隔。第 i 行的第 1 个整数代表第 i 条记录乘坐的交通工具,0 代表地铁,1 代表公交车;第 2 个整数代表第 i 条记录乘车的票价 pricei;第 3 个整数代表第 i 条记录开始乘车的时间 ti(距 0 时刻的分钟数)。
我们保证出行记录是按照开始乘车的时间顺序给出的,且不会有两次乘车记录出现在同一分钟。
输出格式
输出文件有一行,包含一个正整数,代表小轩出行的总花费。
样例
6 0 10 3 1 5 46 0 12 50 1 3 96 0 5 110 1 6 135
36
第一条记录,在第 3 分钟花费 10 元乘坐地铁。
第二条记录,在第 46 分钟乘坐公交车,可以使用第一条记录中乘坐地铁获得的优惠票,因此没有花费。
第三条记录,在第 50 分钟花费 12 元乘坐地铁。
第四条记录,在第 96 分钟乘坐公交车,由于距离第三条记录中乘坐地铁已超过 45 分钟,所以优惠票已失效,花费 3 元乘坐公交车。
第五条记录,在第 110 分钟花费 5 元乘坐地铁。
第六条记录,在第 135 分钟乘坐公交车,由于此时手中只有第五条记录中乘坐地铁获得的优惠票有效,而本次公交车的票价为 6 元,高于第五条记录中地铁的票价 5 元,所以不能使用优惠票,花费 6 元乘坐公交车。
总共花费 36 元。
6 0 5 1 0 20 16 0 7 23 1 18 31 1 4 38 1 7 68
32
第一条记录,在第 1 分钟花费 5 元乘坐地铁。
第二条记录,在第 16 分钟花费 20 元乘坐地铁。
第三条记录,在第 23 分钟花费 7 元乘坐地铁。
第四条记录,在第 31 分钟乘坐公交车,此时只有第二条记录中乘坐的地铁票价高于本次公交车票价,所以使用第二条记录中乘坐地铁获得的优惠票。
第五条记录,在第 38 分钟乘坐公交车,此时第一条和第三条记录中乘坐地铁获得的优惠票都可以使用,使用获得最早的优惠票,即第一条记录中乘坐地铁获得的优惠票。
第六条记录,在第 68 分钟乘坐公交车,使用第三条记录中乘坐地铁获得的优惠票。
总共花费 32 元。
数据范围
对于 30% 的数据,n≤1000,ti≤106。
另有 15% 的数据,ti≤107,所有 pricei 相等。
另有 15% 的数据,ti≤109,所有 pricei 相等。
对于 100% 的数据,n≤105,ti≤109,1≤pricei≤1000。
部分分
- 100 分
全部 20 个测试点等分;数据范围见 constraintsMd 各百分比档。
原文保真说明:原卷印刷错误 1 处(照原卷保留,未作修改)
原卷印刷如此其它name
原卷作
公交换乘原卷第 4 页题目标题印作「公交换乘」;第 1 页题目概况表中文题目名称印作「交通换乘」。本题 name 按题面页标题录入。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <cstdlib>2#include <iostream>3using namespace std;45char encoder[26] = {'C', 'S', 'P', 0};6char decoder[26];78string st;910int main() {11 int k = 0;12 for (int i = 0; i < 26; ++i)13 if (encoder[i] != 0) ++k;14 for (char x = 'A'; x <= 'Z'; ++x) {15 bool flag = true;16 for (int i = 0; i < 26; ++i)17 if (encoder[i] == x) {18 flag = false;19 break;20 }21 if (flag) {22 encoder[k] = x;23 ++k;24 }25 }26 for (int i = 0; i < 26; ++i)27 decoder[encoder[i] - 'A'] = i + 'A';28 cin >> st;29 for (int i = 0; i < st.length(); ++i)30 st[i] = decoder[st[i] - 'A'];31 cout << st;32 return 0;33}- 20单选3 分
•单选题
5) 若输出的字符串为 ABCABCABCA,则下列说法正确的是( )。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <cstdlib>2#include <iostream>3using namespace std;45char encoder[26] = {'C', 'S', 'P', 0};6char decoder[26];78string st;910int main() {11 int k = 0;12 for (int i = 0; i < 26; ++i)13 if (encoder[i] != 0) ++k;14 for (char x = 'A'; x <= 'Z'; ++x) {15 bool flag = true;16 for (int i = 0; i < 26; ++i)17 if (encoder[i] == x) {18 flag = false;19 break;20 }21 if (flag) {22 encoder[k] = x;23 ++k;24 }25 }26 for (int i = 0; i < 26; ++i)27 decoder[encoder[i] - 'A'] = i + 'A';28 cin >> st;29 for (int i = 0; i < st.length(); ++i)30 st[i] = decoder[st[i] - 'A'];31 cout << st;32 return 0;33}- 21单选3 分
若输出的字符串为 CSPCSPCSPCSP,则下列说法正确的是( )。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 √,错误填 ×
#include <iostream>2using namespace std;34long long n, ans;5int k, len;6long long d[1000000];78int main() {9 cin >> n >> k;10 d[0] = 0;11 len = 1;12 ans = 0;13 for (long long i = 0; i < n; ++i) {14 ++d[0];15 for (int j = 0; j + 1 < len; ++j) {16 if (d[j] == k) {17 d[j] = 0;18 d[j + 1] += 1;19 ++ans;20 }21 }22 if (d[len - 1] == k) {23 d[len - 1] = 0;24 d[len] = 1;25 ++len;26 ++ans;27 }28 }29 cout << ans << endl;30 return 0;31}- 22判断1.5 分
若 k=1,则输出 ans 时,len=n。( )
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 √,错误填 ×
#include <iostream>2using namespace std;34long long n, ans;5int k, len;6long long d[1000000];78int main() {9 cin >> n >> k;10 d[0] = 0;11 len = 1;12 ans = 0;13 for (long long i = 0; i < n; ++i) {14 ++d[0];15 for (int j = 0; j + 1 < len; ++j) {16 if (d[j] == k) {17 d[j] = 0;18 d[j + 1] += 1;19 ++ans;20 }21 }22 if (d[len - 1] == k) {23 d[len - 1] = 0;24 d[len] = 1;25 ++len;26 ++ans;27 }28 }29 cout << ans << endl;30 return 0;31}- 23判断1.5 分
若 k>1,则输出 ans 时,len —定小于 n。( )
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <iostream>2using namespace std;34long long n, ans;5int k, len;6long long d[1000000];78int main() {9 cin >> n >> k;10 d[0] = 0;11 len = 1;12 ans = 0;13 for (long long i = 0; i < n; ++i) {14 ++d[0];15 for (int j = 0; j + 1 < len; ++j) {16 if (d[j] == k) {17 d[j] = 0;18 d[j + 1] += 1;19 ++ans;20 }21 }22 if (d[len - 1] == k) {23 d[len - 1] = 0;24 d[len] = 1;25 ++len;26 ++ans;27 }28 }29 cout << ans << endl;30 return 0;31}- 25单选3 分
- 单选题
- 若输入的 n 等于:1015,输入的 k 为 1,则输出等于( )。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <iostream>2using namespace std;34long long n, ans;5int k, len;6long long d[1000000];78int main() {9 cin >> n >> k;10 d[0] = 0;11 len = 1;12 ans = 0;13 for (long long i = 0; i < n; ++i) {14 ++d[0];15 for (int j = 0; j + 1 < len; ++j) {16 if (d[j] == k) {17 d[j] = 0;18 d[j + 1] += 1;19 ++ans;20 }21 }22 if (d[len - 1] == k) {23 d[len - 1] = 0;24 d[len] = 1;25 ++len;26 ++ans;27 }28 }29 cout << ans << endl;30 return 0;31}- 26单选3 分
若输入的 n 等于 205,891,132,094,649(即 330),输入的 k 为 3,则输出等于( )。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <iostream>2using namespace std;34long long n, ans;5int k, len;6long long d[1000000];78int main() {9 cin >> n >> k;10 d[0] = 0;11 len = 1;12 ans = 0;13 for (long long i = 0; i < n; ++i) {14 ++d[0];15 for (int j = 0; j + 1 < len; ++j) {16 if (d[j] == k) {17 d[j] = 0;18 d[j + 1] += 1;19 ++ans;20 }21 }22 if (d[len - 1] == k) {23 d[len - 1] = 0;24 d[len] = 1;25 ++len;26 ++ans;27 }28 }29 cout << ans << endl;30 return 0;31}- 27单选3 分
若输入的 n 等于 100,010,002,000,090,输入的 k 为 10,则输出等于( )。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
(1)(Josephus 问题) 有 n 个人围成一个圈,依次标号 0 至 n−1。从 0 号开始,依次 0,1,0,1,… 交替报数,报到 1 的人会离开,直至圈中只剩下一个人。求最后剩下人的编号。
试补全模拟程序。
#include <iostream>23using namespace std;45const int MAXN = 1000000;6int F[MAXN];78int main() {9 int n;10 cin >> n;11 int i = 0, p = 0, c = 0;12 while (①) {13 if (F[i] == 0) {14 if (②) {15 F[i] = 1;16 ③;17 }18 ④;19 }20 ⑤;21 }22 int ans = -1;23 for (i = 0; i < n; i++)24 if (F[i] == 0)25 ans = i;26 cout << ans << endl;27 return 0;28}- 34(①)单选空位 ①3 分
①处应填( )
A.i < n
B.c < n
C.i < n- 1
D.c < n-1
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
( 2 ) (矩形计数) 平面上有 n 个关键点,求有多少个四条边都和 x 轴或者 y 轴平行的矩形,满足四个顶点都是关键点。给出的关键点可能有重复,但完全重合的矩形只计一 次。
试补全枚举算法。
#include <iostream>23using namespace std;45struct point {6 int x, y, id;7};89bool equals(point a, point b) {10 return a.x == b.x && a.y == b.y;11}1213bool cmp(point a, point b) {14 return ①;15}1617void sort(point A[], int n) {18 for (int i = 0; i < n; i++)19 for (int j = 1; j < n; j++)20 if (cmp(A[j], A[j - 1])) {21 point t = A[j];22 A[j] = A[j - 1];23 A[j - 1] = t;24 }25}2627int unique(point A[], int n) {28 int t = 0;29 for (int i = 0; i < n; i++)30 if (②)31 A[t++] = A[i];32 return t;33}3435bool binary_search(point A[], int n, int x, int y) {36 point p;37 p.x = x;38 p.y = y;39 p.id = n;40 int a = 0, b = n - 1;41 while (a < b) {42 int mid = ③;43 if (④)44 a = mid + 1;45 else46 b = mid;47 }48 return equals(A[a], p);49}5051const int MAXN = 1000;52point A[MAXN];5354int main() {55 int n;56 cin >> n;57 for (int i = 0; i < n; i++) {58 cin >> A[i].x >> A[i].y;59 A[i].id = i;60 }61 sort(A, n);62 n = unique(A, n);63 int ans = 0;64 for (int i = 0; i < n; i++)65 for (int j = 0; j < n; j++)66 if (⑤ && binary_search(A, n, A[i].x, A[j].y) &&67 binary_search(A, n, A[j].x, A[i].y)) {68 ans++;69 }70 cout << ans << endl;71 return 0;72}- 43(⑤)单选空位 ⑤3 分
⑤处应填 ( )
小熊的果篮
C++时间 1 s内存 512 MB 文件 IO:fruit.in → fruit.out
小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子,从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里,具体方法是:每次都把每一个“块”中最左边的水果同时挑出,组成一个果篮。重复这一操作,直至水果用完。注意,每次挑完一个果篮后,“块”可能会发生变化。比如两个苹果“块”之间的唯一桔子被挑走后,两个苹果“块”就变成了一个“块”。请帮小熊计算每个果篮里包含的水果。
输入格式
从文件 fruit.in 中读入数据。
第一行,包含一个正整数 n,表示水果的数量。
第二行,包含 n 个空格分隔的整数,其中第 i 个数表示编号为 i 的水果的种类,1 代表苹果,0 代表桔子。
输出格式
输出到文件 fruit.out 中。
输出若干行。
第 i 行表示第 i 次挑出的水果组成的果篮。从小到大排序输出该果篮中所有水果的编号,每两个编号之间用一个空格分隔。
样例
12 1 1 0 0 1 1 1 0 1 1 0 0
1 3 5 8 9 11 2 4 6 12 7 10
所有水果一开始的情况是 [1,1,0,0,1,1,1,0,1,1,0,0],一共有 6 个块。
在第一次挑水果组成果篮的过程中,编号为 1,3,5,8,9,11 的水果被挑了出来。
之后剩下的水果是 [1,0,1,1,1,0],一共 4 个块。
在第二次挑水果组成果篮的过程中,编号为 2,4,6,12 的水果被挑了出来。
之后剩下的水果是 [1,1],只有 1 个块。
在第三次挑水果组成果篮的过程中,编号为 7 的水果被挑了出来。
最后剩下的水果是 [1],只有 1 个块。
在第四次挑水果组成果篮的过程中,编号为 10 的水果被挑了出来。
20 1 1 1 1 0 0 0 1 1 1 0 0 1 0 1 1 0 0 0 0
1 5 8 11 13 14 15 17 2 6 9 12 16 18 3 7 10 19 4 20
数据范围
对于 10% 的数据,n≤5。
对于 30% 的数据,n≤1000。
对于 70% 的数据,n≤50000。
对于 100% 的数据,1≤n≤2×105。
部分分
- 10 分
对于 10% 的数据,n≤5。
- 20 分
对于 30% 的数据,n≤1000。
- 40 分
对于 70% 的数据,n≤50000。
- 30 分
对于 100% 的数据,1≤n≤2×105。
提示
由于数据规模较大,建议 C/C++ 选手使用 scanf 和 printf 语句输入、输出。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
(1)(枚举因数)从小到大打印正整数 n 的所有正因数。
试补全枚举程序。
#include <bits/stdc++.h>2using namespace std;34int main(){5 int n;6 cin >> n;78 vector<int> fac;9 fac.reserve((int)ceil(sqrt(n)));1011 int i;12 for (i = 1; i * i < n; ++i){13 if (①){14 fac.push_back(i);15 }16 }1718 for (int k = 0; k < fac.size(); ++k){19 cout << ② << "";20 }21 if (③) {22 cout << ④ << "";23 }24 for (int k = fac.size() - 1; k >= 0; --k){25 cout << ⑤ << "";26 }27}- 36(②)单选空位 ②3 分
cout << ② << "";
乘方
C++时间 1 s内存 512 MB 文件 IO:pow.in → pow.out
小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 a 和 b,求 ab 的值是多少。
ab 即 b 个 a 相乘的值,例如 23 即为 3 个 2 相乘,结果为 2×2×2=8。
“简单!”小文心想,同时很快就写出了一份程序,可是测试时却出现了错误。
小文很快意识到,她的程序里的变量都是 int 类型的。在大多数机器上,int 类型能表示的最大数为 231−1,因此只要计算结果超过这个数,她的程序就会出现错误。
由于小文刚刚学会编程,她担心使用 int 计算会出现问题。因此她希望你在 ab 的值超过 109 时,输出一个 -1 进行警示,否则就输出正确的 ab 的值。
然而小文还是不知道怎么实现这份程序,因此她想请你帮忙。
输入格式
从文件 pow.in 中读入数据。
输入共一行,两个正整数 a,b。
输出格式
输出到文件 pow.out 中。
输出共一行,如果 ab 的值不超过 109,则输出 ab 的值,否则输出 -1。
样例
10 9
1000000000
23333 66666
-1
数据范围
对于 10% 的数据,保证 b=1。
对于 30% 的数据,保证 b≤2。
对于 60% 的数据,保证 b≤30,ab≤1018。
对于 100% 的数据,保证 1≤a,b≤109。
部分分
- 10 分
测试点 1:10% 数据,保证 b=1。
- 20 分
测试点 2,3:30% 数据,保证 b≤2。
- 30 分
测试点 4,5,6:60% 数据,保证 b≤30,ab≤1018。
- 40 分
测试点 7∼10:100% 数据,保证 1≤a,b≤109。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include<iostream>2#include<cmath>3using namespace std;45double f(double a,double b,double c){6 double s=(a+b+c)/2;7 return sqrt(s*(s-a)*(s-b)*(s-c));8}9int main(){10 cout.flags(ios::fixed);11 cout.precision(4);12 13 int a,b,c;14 cin>>a>>b>>c;15 cout<<f(a,b,c)<<endl;16 return 0;17}- 16判断2 分
(2分)当输入为
2 2 2时,输出为1.7321( )
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include<iostream>2#include<cmath>3using namespace std;45double f(double a,double b,double c){6 double s=(a+b+c)/2;7 return sqrt(s*(s-a)*(s-b)*(s-c));8}9int main(){10 cout.flags(ios::fixed);11 cout.precision(4);12 13 int a,b,c;14 cin>>a>>b>>c;15 cout<<f(a,b,c)<<endl;16 return 0;17}- 19单选3 分
单选题
- 当输入为
3 4 5时,输出为( )
- 当输入为
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include<iostream>2#include<cmath>3using namespace std;45double f(double a,double b,double c){6 double s=(a+b+c)/2;7 return sqrt(s*(s-a)*(s-b)*(s-c));8}9int main(){10 cout.flags(ios::fixed);11 cout.precision(4);12 13 int a,b,c;14 cin>>a>>b>>c;15 cout<<f(a,b,c)<<endl;16 return 0;17}- 20单选3 分
当输入为
5 12 13时,输出为( )
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include<iostream>2#include<vector>3#include<algorithm>4using namespace std;56int f(string x,string y){7 int m=x.size();8 int n=y.size();9 vector<vector<int>>v(m+1,vector<int>(n+1,0));10 for(int i=1;i<=m;i++){11 for(int j=1;j<=n;j++){12 if(x[i-1]==y[j-1]){13 v[i][j]=v[i-1][j-1]+1;14 }else{15 v[i][j]=max(v[i-1][j],v[i][j-1]);16 }17 }18 }19 return v[m][n];20}21bool g(string x,string y){22 if(x.size() != y.size()){23 return false;24 }25 return f(x+x,y)==y.size();26}27int main(){28 string x,y;29 cin>>x>>y;30 cout<<g(x,y)<<endl;31 return 0;32}- 25单选3 分
当输入为
csp-j p-jcs时,输出为()。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include<iostream>2#include<vector>3#include<algorithm>4using namespace std;56int f(string x,string y){7 int m=x.size();8 int n=y.size();9 vector<vector<int>>v(m+1,vector<int>(n+1,0));10 for(int i=1;i<=m;i++){11 for(int j=1;j<=n;j++){12 if(x[i-1]==y[j-1]){13 v[i][j]=v[i-1][j-1]+1;14 }else{15 v[i][j]=max(v[i-1][j],v[i][j-1]);16 }17 }18 }19 return v[m][n];20}21bool g(string x,string y){22 if(x.size() != y.size()){23 return false;24 }25 return f(x+x,y)==y.size();26}27int main(){28 string x,y;29 cin>>x>>y;30 cout<<g(x,y)<<endl;31 return 0;32}- 26单选3 分
当输入为
csppsc spsccp时,输出为()。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <iostream>2#include <cmath>3using namespace std;45int solve1(int n){6 return n*n;7}89int solve2(int n){10 int sum=0;11 for(int i=1;i<=sqrt(n);i++){12 if(n%i==0){13 if(n/i==i){14 sum+=i*i;15 }else{16 sum+=i*i+(n/i)*(n/i);17 }18 }19 }20 return sum;21}22int main(){23 int n;24 cin>>n;25 cout<<solve2(solve1(n))<<" "<<solve1((solve2(n)))<<endl;26 return 0;27}- 32单选3 分
当输入为
5时,输出为( )
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 √,错误填 ×
#include <iostream>2using namespace std;34bool isPrime(int n) {5 if (n <= 1) {6 return false;7 }8 for (int i = 2; i * i <= n; i++) {9 if (n % i == 0) {10 return false;11 }12 }13 return true;14}1516int countPrimes(int n) {17 int count = 0;18 for (int i = 2; i <= n; i++) {19 if (isPrime(i)) {20 count++;21 }22 }23 return count;24}2526int sumPrimes(int n) {27 int sum = 0;28 for (int i = 2; i <= n; i++) {29 if (isPrime(i)) {30 sum += i;31 }32 }33 return sum;34}3536int main() {37 int x;38 cin >> x;39 cout << countPrimes(x) << " " << sumPrimes(x) << endl;40 return 0;41}- 16判断1.5 分
当输入为 10 时,程序的第一个输出为 4 ,第二个输出为 17。()
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <iostream>2using namespace std;34bool isPrime(int n) {5 if (n <= 1) {6 return false;7 }8 for (int i = 2; i * i <= n; i++) {9 if (n % i == 0) {10 return false;11 }12 }13 return true;14}1516int countPrimes(int n) {17 int count = 0;18 for (int i = 2; i <= n; i++) {19 if (isPrime(i)) {20 count++;21 }22 }23 return count;24}2526int sumPrimes(int n) {27 int sum = 0;28 for (int i = 2; i <= n; i++) {29 if (isPrime(i)) {30 sum += i;31 }32 }33 return sum;34}3536int main() {37 int x;38 cin >> x;39 cout << countPrimes(x) << " " << sumPrimes(x) << endl;40 return 0;41}- 19单选3 分
单选题
- 当输入为 50 时,
sumPrimes(50)的输出为( )。
- 当输入为 50 时,
地图探险
C++时间 1 s内存 512 MB 文件 IO:explore.in → explore.out
小 A 打算前往一片丛林去探险。丛林的地理环境十分复杂,为了防止迷路,他先派遣了一个机器人前去探路。
丛林的地图可以用一个 n 行 m 列的字符表来表示。我们将第 i 行第 j 列的位置的坐标记作 (i,j)(1≤i≤n,1≤j≤m)。如果这个位置的字符为 x,即代表这个位置上有障碍,不可通过。反之,若这个位置的字符为 .,即代表这个位置是一片空地,可以通过。
这个机器人的状态由位置和朝向两部分组成。其中位置由坐标 (x,y)(1≤x≤n,1≤y≤m) 刻画,它表示机器人处在地图上第 x 行第 y 列的位置。而朝向用一个 0∼3 的整数 d 表示,其中 d=0 代表向东,d=1 代表向南,d=2 代表向西,d=3 代表向北。
初始时,机器人的位置为 (x0,y0),朝向为 d0。保证初始时机器人所在的位置为空地。接下来机器人将要进行 k 次操作。每一步,机器人将按照如下的模式操作:
假设机器人当前处在的位置为 (x,y),朝向为 d。则它的方向上的下一步的位置 (x′,y′) 定义如下:若 d=0,则令 (x′,y′)=(x,y+1),若 d=1,则令 (x′,y′)=(x+1,y),若 d=2,则令 (x′,y′)=(x,y−1),若 d=3,则令 (x′,y′)=(x−1,y)。
接下来,机器人判断它下一步的位置是否在地图内,且是否为空地。具体地说,它判断 (x′,y′) 是否满足 1≤x′≤n,1≤y′≤m,且 (x′,y′) 位置上是空地。如果条件成立,则机器人会向前走一步。它新的位置变为 (x′,y′),且朝向不变。如果条件不成立,则它会执行“向右转”操作。也就是说,令 d′=(d+1)mod4(即 d+1 除以 4 的余数),且它所处的位置保持不变,但朝向由 d 变为 d′。
小 A 想要知道,在机器人执行完 k 步操作之后,地图上所有被机器人经过的位置(包括起始位置)有几个。
输入格式
从文件 explore.in 中读入数据。
本题有多组测试数据。
输入的第一行包含一个正整数 T,表示数据组数。
接下来包含 T 组数据,每组数据的格式如下:
第一行包含三个正整数 n,m,k。其中 n,m 表示地图的行数和列数,k 表示机器人执行操作的次数。
第二行包含两个正整数 x0,y0 和一个非负整数 d0。
接下来 n 行,每行包含一个长度为 m 的字符串。保证字符串中只包含 x 和 . 两个字符。其中,第 x 行的字符串的第 y 个字符代表的位置为 (x,y)。这个位置是 x 即代表它是障碍,否则代表它是空地。数据保证机器人初始时所在的位置为空地。
输出格式
输出到文件 explore.out 中。
对于每组数据:输出一行包含一个正整数,表示地图上所有被机器人经过的位置(包括起始位置)的个数。
样例
2 1 5 4 1 1 2 ....x 5 5 20 1 1 0 ..... .xxx. .x.x. ..xx. x....
3 13
该样例包含两组数据。对第一组数据,机器人的状态以如下方式变化:
- 初始时,机器人位于位置 (1,1),方向朝西(用数字 2 代表)。
- 第一步,机器人发现它下一步的位置 (1,0) 不在地图内,因此,它会执行“向右转”操作。此时,它的位置仍然为 (1,1),但方向朝北(用数字 3 代表)。
- 第二步,机器人发现它下一步的位置 (0,1) 不在地图内,因此,它仍然会执行“向右转”操作。此时,它的位置仍然为 (1,1),但方向朝东(用数字 0 代表)。
- 第三步,机器人发现它下一步的位置 (1,2) 在地图内,且为空地。因此,它会向东走一步。此时,它的位置变为 (1,2),方向仍然朝东。
- 第四步,机器人发现它下一步的位置 (1,3) 在地图内,且为空地。因此,它会向东走一步。此时,它的位置变为 (1,3),方向仍然朝东。
因此,四步之后,机器人经过的位置有三个,分别为 (1,1),(1,2),(1,3)。
对第二组数据,机器人依次执行的操作指令为:向东走到 (1,2),向东走到 (1,3),向东走到 (1,4),向东走到 (1,5),向右转,向南走到 (2,5),向南走到 (3,5),向南走到 (4,5),向南走到 (5,5),向右转,向西走到 (5,4),向西走到 (5,3),向西走到 (5,2),向右转,向北走到 (4,2),向右转,向右转,向南走到 (5,2),向右转,向右转。
数据范围
对于所有测试数据,保证:1≤T≤5,1≤n,m≤103,1≤k≤106,1≤x0≤n,1≤y0≤m,0≤d0≤3,且机器人的起始位置为空地。
| 测试点编号 | n | m | k | 特殊性质 |
|---|---|---|---|---|
| 1,2 | =1 | ≤2 | =1 | 无 |
| 3,4 | ≤102 | ≤102 | =1 | 无 |
| 5 | =1 | ≤103 | ≤2×103 | 地图上所有位置均为空地 |
| 6 | =1 | ≤103 | ≤2×103 | 无 |
| 7 | ≤103 | ≤103 | ≤106 | 地图上所有位置均为空地 |
| 8∼10 | ≤103 | ≤103 | ≤106 | 无 |
部分分
- 20 分
测试点 1,2:n=1,m≤2,k=1,无特殊性质。
- 20 分
测试点 3,4:n,m≤102,k=1,无特殊性质。
- 10 分
测试点 5:n=1,m≤103,k≤2×103,地图上所有位置均为空地。
- 10 分
测试点 6:n=1,m≤103,k≤2×103,无特殊性质。
- 10 分
测试点 7:n,m≤103,k≤106,地图上所有位置均为空地。
- 30 分
测试点 8∼10:n,m≤103,k≤106,无特殊性质。
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写其它数据范围
原卷作
| $1, 2$ | $=1$ | $\le 2$ | $=1$ | 无 |洛谷 P11228 测试点表将第 1–2 档与第 3–4 档拆成多行并用 ^ 继承,且第 7 档 $m$ 列写 ^;官方 PDF 第 8 页图像为准:$1,2$ 合并为 $n=1,m\le2,k=1$;$3,4$ 为 $n,m\le10^2,k=1$;第 7 档 $m\le10^3$ 显式给出。
已按官方原件恢复:现为原卷原文
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 A,错误填 B
#include <algorithm>2#include <cstdio>3#include <cstring>4inline int gcd(int a, int b) {5 if (b == 0)6 return a;7 return gcd(b, a % b);8}9int main() {10 int n;11 scanf("%d", &n);12 int ans = 0;13 for (int i = 1; i <= n; ++i) {14 for (int j = i + 1; j <= n; ++j) {15 for (int k = j + 1; k <= n; ++k) {16 if (gcd(i, j) == 1 && gcd(j, k) == 117 && gcd(i, k) == 1) {18 ++ans;19 }20 }21 }22 }23 printf("%d\n", ans);24 return 0;25}- 18判断1.5 分
当输入的 n≥3 的时候,程序总是输出一个正整数。( )
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
#include <algorithm>2#include <cstdio>3#include <cstring>4inline int gcd(int a, int b) {5 if (b == 0)6 return a;7 return gcd(b, a % b);8}9int main() {10 int n;11 scanf("%d", &n);12 int ans = 0;13 for (int i = 1; i <= n; ++i) {14 for (int j = i + 1; j <= n; ++j) {15 for (int k = j + 1; k <= n; ++k) {16 if (gcd(i, j) == 1 && gcd(j, k) == 117 && gcd(i, k) == 1) {18 ++ans;19 }20 }21 }22 }23 printf("%d\n", ans);24 return 0;25}- 20单选3 分
当输入为 8 的时候,输出为( )。
座位
C++时间 1 s内存 512 MB 文件 IO:seat.in → seat.out
CSP-J 2025 第二轮正在进行。小 R 所在的考场共有 n×m 名考生,其中所有考生的 CSP-J 2025 第一轮成绩互不相同。所有 n×m 名考生将按照 CSP-J 2025 第一轮的成绩,由高到低蛇形分配座位,排列成 n 行 m 列。具体地,设小 R 所在的考场的所有考生的成绩从高到低分别为 s1>s2>⋯>sn×m,则成绩为 s1 的考生的座位为第 1 列第 1 行,成绩为 s2 的考生的座位为第 1 列第 2 行,……,成绩为 sn 的考生的座位为第 1 列第 n 行,成绩为 sn+1 的考生的座位为第 2 列第 n 行,……,成绩为 s2n 的考生的座位为第 2 列第 1 行,成绩为 s2n+1 的考生的座位为第 3 列第 1 行,以此类推。
例如,若 n=4,m=5,则所有 4×5=20 名考生将按照 CSP-J 2025 第一轮成绩从高到低的顺序,根据下图中的箭头顺序蛇形分配座位。

给定小 R 所在的考场座位的行数 n 与列数 m,以及小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩 a1,a2,…,an×m,其中 a1 为小 R CSP-J 2025 第一轮的成绩,你需要帮助小 R 求出,他的座位为第几列第几行。
输入格式
从文件 seat.in 中读入数据。
输入的第一行包含两个正整数 n,m,分别表示小 R 所在的考场座位的行数与列数。
输入的第二行包含 n×m 个正整数 a1,a2,…,an×m,分别表示小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩,其中 a1 为小 R CSP-J 2025 第一轮的成绩。
输出格式
输出到文件 seat.out 中。
输出一行两个正整数 c,r,表示小 R 的座位为第 c 列第 r 行。
样例
2 2 99 100 97 98
1 2
按照成绩从高到低的顺序,成绩为 100 的考生的座位为第 1 列第 1 行,成绩为 99 的考生的座位为第 1 列第 2 行,成绩为 98 的考生的座位为第 2 列第 2 行,成绩为 97 的考生的座位为第 2 列第 1 行。小 R 的成绩为 99,因此座位为第 1 列第 2 行。
2 2 98 99 100 97
2 2
按照成绩从高到低的顺序,成绩为 100 的考生的座位为第 1 列第 1 行,成绩为 99 的考生的座位为第 1 列第 2 行,成绩为 98 的考生的座位为第 2 列第 2 行,成绩为 97 的考生的座位为第 2 列第 1 行。小 R 的成绩为 98,因此座位为第 2 列第 2 行。
3 3 94 95 96 97 98 99 100 93 92
3 1
数据范围
对于所有测试数据,保证:
- 1≤n≤10,1≤m≤10;
- 对于所有 1≤i≤n×m,均有 1≤ai≤100,且 a1,a2,…,an×m 互不相同。
| 测试点编号 | n≤ | m≤ | 特殊性质 |
|---|---|---|---|
| 1 | 1 | 1 | AB |
| 2,3 | 1 | 10 | 无 |
| 4,5 | 10 | 1 | 无 |
| 6 | 2 | 2 | A |
| 7 | 2 | 2 | B |
| 8,9 | 2 | 2 | 无 |
| 10 | 2 | 10 | A |
| 11 | 2 | 10 | B |
| 12∼14 | 2 | 10 | 无 |
| 15∼17 | 10 | 2 | 无 |
| 18∼20 | 10 | 10 | 无 |
特殊性质 A:对于所有 1≤i≤n×m,均有 ai=i。
特殊性质 B:对于所有 1≤i≤n×m,均有 ai=n×m−i+1。
部分分
- 5 分
测试点 1:n≤1,m≤1,特殊性质 A、B。
- 10 分
测试点 2,3:n≤1,m≤10,无特殊性质。
- 10 分
测试点 4,5:n≤10,m≤1,无特殊性质。
- 5 分
测试点 6:n≤2,m≤2,特殊性质 A。
- 5 分
测试点 7:n≤2,m≤2,特殊性质 B。
- 10 分
测试点 8,9:n≤2,m≤2,无特殊性质。
- 5 分
测试点 10:n≤2,m≤10,特殊性质 A。
- 5 分
测试点 11:n≤2,m≤10,特殊性质 B。
- 15 分
测试点 12∼14:n≤2,m≤10,无特殊性质。
- 15 分
测试点 15∼17:n≤10,m≤2,无特殊性质。
- 15 分
测试点 18∼20:n≤10,m≤10,无特殊性质。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB