选择题 共15道
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15阅读程序 共17道
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32完善程序 共10道
33 34 35 36 37 38 39 40 41 42737 2024年CCF非专业级别软件能力认证第一轮 (CSP-S)提高级C++语言试题-练习
选择题 共15道
01 在 Linux 系统中,如果你想显示当前工作目录的路径,应该使用哪个命令? 2分
登录后查看选项
02 假设一个长度为 n 的整数数组中每个元素互不相同,且这个数组是无序的。要找到这个数组中最大元素的时间复杂度是多少? 2分
登录后查看选项
03 在 C++中,以下哪个函数调用会造成栈溢出? 2分
登录后查看选项
04 在一场比赛中,有 10 名选手参加,前三名将获得金银铜牌,若不允许并列,且每名选手只能获得一枚铜牌,则不同的颁奖方式共有多少种? 2分
登录后查看选项
05 下面那个数据结构最适合实现先进先出(FIFO)的功能? 2分
登录后查看选项
06 一直 f(1)=1,且对于 n>=2 有 f(n) = f(n - 1) + f([n/2]),则 f(4) 的值为: 2分
登录后查看选项
07 假设一个包含 n 个顶点的无向图,且该图是欧拉图。一下关于该图的描述中哪一项不一定正确? 2分
登录后查看选项
08 对数组进行二分查找的过程中,以下哪个条件必须满足? 2分
登录后查看选项
09 考虑一个自然数n以及一个模数m,你需要计算n的逆元(即n在模m意义下的乘法逆元)。下列哪种算法最为合适? 2分
登录后查看选项
10 在设计一个哈希表时,为了减少冲突,需要使用适当的哈希函数和和冲突解决策略。已知某哈希表中有n个键值对,表的装载因子为a(0 2分
登录后查看选项
11 假设有一颗h层的完全二叉树,该树最多包含多少个节点 2分
登录后查看选项
12 设有一个10个顶点的完全图,每两个顶点之间都有一条边,有多少个长度为4的环? 2分
登录后查看选项
13 对于一个整数n,定义f(n)为n的各个位数之和,问使f(f(x))=10的最小自然数x是多少? 2分
登录后查看选项
14 设有一个长度为n的01字符串,其中有k个1,每次操作可以交换相邻两个字符。在最坏的情况下将这k个1移到字符串最右边所需要的交换次数是多少? 2分
登录后查看选项
15 如图是一张包含 7 个顶点的有向图。如果要删除一些边,使得从节点 1 到节点 7 没有可行路径,且删除的边数最少,请问总共有多少种可行的删除边的集合? 2分
登录后查看选项
阅读程序 共17道
16
阅读程序
#include <iostream>
using namespace std;
const int N = 1000;
int c[N];
int logic(int x, int y) {
return (x & y) ^ ((x ^ y) | (x & y));
}
void generate(int a, int b, int *c) {
for (int i = 0; i < b; i++) {
c[i] = logic(a, i) % (b + 1);
}
}
void recursion(int depth, int *arr, int size) {
if (depth <= 0 || size <= 1) return;
int pivot = arr[0];
int i = 0, j = size - 1;
while (i <= j) {
while (arr[i] < pivot) i++;
while (arr[j] > pivot) j--;
if (i <= j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
}
}
recursion(depth - 1, arr, j + 1);
recursion(depth - 1, arr + i, size - i);
}
int main() {
int a, b, d;
cin >> a >> b >> d;
generate(a, b, c);
recursion(d, c, b);
for (int i = 0; i < b; i++) cout << c[i] << " ";
}
当 1000 ≥ b = b 时,输出的序列是有序的
1.5分
#include <iostream>
using namespace std;
const int N = 1000;
int c[N];
int logic(int x, int y) {
return (x & y) ^ ((x ^ y) | (x & y));
}
void generate(int a, int b, int *c) {
for (int i = 0; i < b; i++) {
c[i] = logic(a, i) % (b + 1);
}
}
void recursion(int depth, int *arr, int size) {
if (depth <= 0 || size <= 1) return;
int pivot = arr[0];
int i = 0, j = size - 1;
while (i <= j) {
while (arr[i] < pivot) i++;
while (arr[j] > pivot) j--;
if (i <= j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
}
}
recursion(depth - 1, arr, j + 1);
recursion(depth - 1, arr + i, size - i);
}
int main() {
int a, b, d;
cin >> a >> b >> d;
generate(a, b, c);
recursion(d, c, b);
for (int i = 0; i < b; i++) cout << c[i] << " ";
}
登录后查看选项
17 当输入“5 5 1”时,输出为“1 1 5 5 5” 1.5分
登录后查看选项
18 假设数组 c 长度无限制,该程序所实现的算法的时间复杂度是 O(b) 的 1.5分
登录后查看选项
19 函数 int logic(int x, int y) 的功能是 3分
登录后查看选项
20 当输入为“10 100 100”时,输出的第 100 个数是 4分
登录后查看选项
21
阅读程序2
#include
#include
using namespace std;
const int P = 998244353, N = 1e4 + 10, M = 20;
int n, m;
string s;
int dp[1 << M];
int solve() {
dp[0] = 1;
for (int i = 0; i < n; i++) {
for (int j = (1 << (m - 1)) - 1; j >= 0; j--) {
int k = (j << 1) | (s[i] - '0');
if (j != 0 || s[j] == '1')
dp[k] = (dp[k] + dp[j]) % P;
}
}
int ans = 0;
for (int i = 0; i < (1 << m); i++) {
ans = (ans + 1ll * i * dp[i]) % P;
}
return ans;
}
int solve2() {
int ans = 0;
for (int i = 0; i < (1 << n); i++) {
int cnt = 0;
int num = 0;
for (int j = 0; j < n; j++) {
if (i & (1 << j)) {
num = num * 2 + (s[j] - '0');
cnt++;
}
}
if (cnt <= m) (ans += num) %= P;
}
return ans;
}
int main() {
cin >> n >> m;
cin >> s;
if (n <= 20) {
cout << solve2() << endl;
}
cout << solve() << endl;
return 0;
}
假设输入的 s 是包含 n 个字符的 01 串,函数 solve() 所实现的算法时间复杂度是 O(n*2^m)。
1.5分
#include
#include
using namespace std;
const int P = 998244353, N = 1e4 + 10, M = 20;
int n, m;
string s;
int dp[1 << M];
int solve() {
dp[0] = 1;
for (int i = 0; i < n; i++) {
for (int j = (1 << (m - 1)) - 1; j >= 0; j--) {
int k = (j << 1) | (s[i] - '0');
if (j != 0 || s[j] == '1')
dp[k] = (dp[k] + dp[j]) % P;
}
}
int ans = 0;
for (int i = 0; i < (1 << m); i++) {
ans = (ans + 1ll * i * dp[i]) % P;
}
return ans;
}
int solve2() {
int ans = 0;
for (int i = 0; i < (1 << n); i++) {
int cnt = 0;
int num = 0;
for (int j = 0; j < n; j++) {
if (i & (1 << j)) {
num = num * 2 + (s[j] - '0');
cnt++;
}
}
if (cnt <= m) (ans += num) %= P;
}
return ans;
}
int main() {
cin >> n >> m;
cin >> s;
if (n <= 20) {
cout << solve2() << endl;
}
cout << solve() << endl;
return 0;
}
登录后查看选项
22 输入 “11 2 10000000001” 时,程序输出两个数 32 和 23。 1.5分
登录后查看选项
23 在 n<=10 时,solve() 的返回值始终小于 4^10 2分
登录后查看选项
24 当 n=10 且 m=10 时,有多少种输入使得两行的结果完全一致? 3分
登录后查看选项
25 当 n<=5 时,solve() 的最大可能返回值为? 3分
登录后查看选项
26 若 n=8, m=8, solve 和 solve2 的返回值的最大可能的差值为 3分
登录后查看选项
27
阅读程序3
#include < iostream >
#include < cstring >
#include < algorithm >
using namespace std;
const int maxn = 1000000 + 5;
const int P1 = 998244353, P2 = 1000000007;
const int B1 = 2, B2 = 31;
const int K1 = 0, K2 = 13;
typedef long long II;
int n;
bool p[maxn];
int p1[maxn], p2[maxn];
struct H {
int h1, h2, l;
H(bool b = false) {
h1 = b + K1;
h2 = b + K2;
l = 1;
}
H operator + (const H &h)const {
H hh;
hh.l = l + h.l;
hh.h1 = (1ll * h1 * p1[h.l] + h.h1) % P1;
hh.h2 = (1ll * h2 * p2[h.l] + h.h2) % P2;
return hh;
}
bool operator == (const H &h)const {
return l == h.l && h1 == h.h1 && h2 == h.h2;
}
bool operator <(const H &h)const {
if (l != h.l) return l < h.l;
else if (h1 != h.h1) return h1 < h.h1;
else return h2 < h.h2;
}
} h[maxn];
void init() {
memset(p, 1, sizeof(p));
p[0] = p[1] = false;
p1[0] = p2[0] = 1;
for (int i = 1; i <= n; i++) {
p1[i] = (1ll * B1 * p1[i - 1]) % P1;
p2[i] = (1ll * B2 * p2[i - 1]) % P2;
if (!p[i])continue;
for (int j = 2 * i; j <= n; j += i) {
p[j] = false;
}
}
}
int solve() {
for (int i = n; i; i--) {
h[i] = H(p[i]);
if (2 * i + 1 <= n) {
h[i] = h[2 * i] + h[i] + h[2 * i + 1];
} else if (2 * i <= n) {
h[i] = h[2 * i] + h[i];
}
}
cout << h[1].h1 << endl;
sort(h + 1, h + n + 1);
int m = unique(h + 1, h + n + 1) - (h + 1);
return m;
}
int main() {
cin >> n;
init();
cout << solve() << endl;
}
假设程序运行前能自动将 maxn 改为 n+1,所实现的算法的时间复杂度是 O(nlogn)。
1.5分
#include < iostream >
#include < cstring >
#include < algorithm >
using namespace std;
const int maxn = 1000000 + 5;
const int P1 = 998244353, P2 = 1000000007;
const int B1 = 2, B2 = 31;
const int K1 = 0, K2 = 13;
typedef long long II;
int n;
bool p[maxn];
int p1[maxn], p2[maxn];
struct H {
int h1, h2, l;
H(bool b = false) {
h1 = b + K1;
h2 = b + K2;
l = 1;
}
H operator + (const H &h)const {
H hh;
hh.l = l + h.l;
hh.h1 = (1ll * h1 * p1[h.l] + h.h1) % P1;
hh.h2 = (1ll * h2 * p2[h.l] + h.h2) % P2;
return hh;
}
bool operator == (const H &h)const {
return l == h.l && h1 == h.h1 && h2 == h.h2;
}
bool operator <(const H &h)const {
if (l != h.l) return l < h.l;
else if (h1 != h.h1) return h1 < h.h1;
else return h2 < h.h2;
}
} h[maxn];
void init() {
memset(p, 1, sizeof(p));
p[0] = p[1] = false;
p1[0] = p2[0] = 1;
for (int i = 1; i <= n; i++) {
p1[i] = (1ll * B1 * p1[i - 1]) % P1;
p2[i] = (1ll * B2 * p2[i - 1]) % P2;
if (!p[i])continue;
for (int j = 2 * i; j <= n; j += i) {
p[j] = false;
}
}
}
int solve() {
for (int i = n; i; i--) {
h[i] = H(p[i]);
if (2 * i + 1 <= n) {
h[i] = h[2 * i] + h[i] + h[2 * i + 1];
} else if (2 * i <= n) {
h[i] = h[2 * i] + h[i];
}
}
cout << h[1].h1 << endl;
sort(h + 1, h + n + 1);
int m = unique(h + 1, h + n + 1) - (h + 1);
return m;
}
int main() {
cin >> n;
init();
cout << solve() << endl;
}
登录后查看选项
28 时间开销的瓶颈是 init()函数 1.5分
登录后查看选项
29 若修改常数 B1 或 K1 的值,该程序可能会输出不同呢的结果 1.5分
登录后查看选项
30 在 solve()函数种,h[]的合并顺序可以看作是: 3分
登录后查看选项
31 输入 “10”,输出的第一行是? 3分
登录后查看选项
32 输入 “16”,输出的第二行是? 4分
登录后查看选项
完善程序 共10道
33
完善程序(单选题,每小题 3 分,共计 30 分)
合并序列,有两个长度为 N 的单调不降序列 A 和 B,序列的每个元素都是小于 10^9
的非负整数。在 A 和 B 中各取一个数相加可以得到 N^2 个和,求其中第 k 小的和。上述参
数满足 N<=10^5 和 1<=K<=N^2
#include < iostream >
using namespace std;
const int maxn = 100005;
int n;
long long k;
int a[maxn], b[maxn];
int *upper_bound(int *a, int *an, int ai) {
int l = 0, r = ______(1)______;
while (l < r) {
int mid = (l + r) >> 1;
if (______(2)______) {
r = mid;
} else {
l = mid + 1;
}
}
return ______(3)______;
}
long long get_rank(int sum) {
long long rank = 0;
for (int i = 0; i < n; i++) {
rank += upper_bound(b, b + n, sum - a[i]) - b;
}
return rank;
}
int solve() {
int i = 0, r = ______(4)______;
while (i < r) {
int mid = ((long long)! + r) >> 1;
if (______(5)______) {
i = mid + 1;
} else {
r = mid;
}
}
return i;
}
int main() {
cin >> n >> k;
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
cin >> b[i];
cout << solve() << endl;
return 0;
}
(1)处应填
3分
#include < iostream >
using namespace std;
const int maxn = 100005;
int n;
long long k;
int a[maxn], b[maxn];
int *upper_bound(int *a, int *an, int ai) {
int l = 0, r = ______(1)______;
while (l < r) {
int mid = (l + r) >> 1;
if (______(2)______) {
r = mid;
} else {
l = mid + 1;
}
}
return ______(3)______;
}
long long get_rank(int sum) {
long long rank = 0;
for (int i = 0; i < n; i++) {
rank += upper_bound(b, b + n, sum - a[i]) - b;
}
return rank;
}
int solve() {
int i = 0, r = ______(4)______;
while (i < r) {
int mid = ((long long)! + r) >> 1;
if (______(5)______) {
i = mid + 1;
} else {
r = mid;
}
}
return i;
}
int main() {
cin >> n >> k;
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
cin >> b[i];
cout << solve() << endl;
return 0;
}
登录后查看选项
34 (2)处应填 3分
登录后查看选项
35 (3)处应填 3分
登录后查看选项
36 (4)处应填 3分
登录后查看选项
37 (5)处应填 3分
登录后查看选项
38
(次短路)已知有一个 n 个点 m 条边的有向图 G,并且给定图中的两个点 s 和 t,求次
短路(长度严格大于最短路的最短路径)。如果不存在,输出一行“-1”。如果存在,输出两
行,第一行表示此段路经的长度,第二行表示此段路的一个方案
#include < cstdio >
#include < queue >
#include < utility >
#include < cstring >
using namespace std;
const int maxn = 2e5 + 10, maxm = 1e6 + 10, inf = 522133279;
int n, m, s, t;
int head[maxn], nxt[maxm], to[maxm], w[maxm], tot = 1;
int dis[maxn << 1], *dis2;
int pre[maxn << 1], *pre2;
bool vis[maxn << 1];
void add(int a, int b, int c) {
++tot;
nxt[tot] = head[a];
to[tot] = b;
w[tot] = c;
head[a] = tot;
}
bool upd(int a, int b, int d, priority_queue>& q) {
if (d >= dis[b]) return false;
if (b < n) ______(1)______;
q.push(______(2)______);
dis[b] = d;
pre[b] = a;
return true;
}
void solve() {
priority_queue> q;
q.push(make_pair(0, s));
memset(dis, ______(3)______, sizeof(dis));
memset(pre, -1, sizeof(pre));
dis2 = dis + n;
pre2 = pre + n;
dis[s] = 0;
while (!q.empty()) {
int aa = q.top().second; q.pop();
if (vis[aa]) continue;
vis[aa] = true;
int a = aa % n;
for (int e = head[a]; e; e = nxt[e]) {
int b = to[e], c = w[e];
if (aa < n) {
if (upd(a, b, dis[a] + c, q))
______(4)______;
} else {
upd(n + a, n + b, dis2[a] + c, q);
}
}
}
}
void out(int a) {
if (a != s) {
if (a < n)
out(pre[a]);
else
out(______(5)______);
}
printf("%d%s", a % n + 1, (a == n + t) ? "\n" : " ");
}
int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
s--, t--;
for (int i = 0; i < m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a - 1, b - 1, c);
}
solve();
if (dis2[t] == inf)
puts("-1");
else {
printf("%d\n", dis2[t]);
out(n + t);
}
return 0;
}
(1)处应填
3分
#include < cstdio >
#include < queue >
#include < utility >
#include < cstring >
using namespace std;
const int maxn = 2e5 + 10, maxm = 1e6 + 10, inf = 522133279;
int n, m, s, t;
int head[maxn], nxt[maxm], to[maxm], w[maxm], tot = 1;
int dis[maxn << 1], *dis2;
int pre[maxn << 1], *pre2;
bool vis[maxn << 1];
void add(int a, int b, int c) {
++tot;
nxt[tot] = head[a];
to[tot] = b;
w[tot] = c;
head[a] = tot;
}
bool upd(int a, int b, int d, priority_queue>& q) {
if (d >= dis[b]) return false;
if (b < n) ______(1)______;
q.push(______(2)______);
dis[b] = d;
pre[b] = a;
return true;
}
void solve() {
priority_queue> q;
q.push(make_pair(0, s));
memset(dis, ______(3)______, sizeof(dis));
memset(pre, -1, sizeof(pre));
dis2 = dis + n;
pre2 = pre + n;
dis[s] = 0;
while (!q.empty()) {
int aa = q.top().second; q.pop();
if (vis[aa]) continue;
vis[aa] = true;
int a = aa % n;
for (int e = head[a]; e; e = nxt[e]) {
int b = to[e], c = w[e];
if (aa < n) {
if (upd(a, b, dis[a] + c, q))
______(4)______;
} else {
upd(n + a, n + b, dis2[a] + c, q);
}
}
}
}
void out(int a) {
if (a != s) {
if (a < n)
out(pre[a]);
else
out(______(5)______);
}
printf("%d%s", a % n + 1, (a == n + t) ? "\n" : " ");
}
int main() {
scanf("%d%d%d%d", &n, &m, &s, &t);
s--, t--;
for (int i = 0; i < m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a - 1, b - 1, c);
}
solve();
if (dis2[t] == inf)
puts("-1");
else {
printf("%d\n", dis2[t]);
out(n + t);
}
return 0;
}
登录后查看选项
39 (2)处应填 3分
登录后查看选项
40 (3)处应填 3分
登录后查看选项
41 (4)处应填 3分
登录后查看选项
42 (5)处应填 3分
登录后查看选项