题目一:
AC代码
#include <stdio.h>#define N 1000000typedef long long l;int main() {int n, m;l s = 0;l a[N + 1], b[N + 1];int i = 1, j = 1;scanf("%d %d", &n, &m);for (int k = 1; k <= n; k++) {scanf("%lld", &a[k]);}for (int k = 1; k <= m; k++) {scanf("%lld", &b[k]);}while (i <= n && j <= m) {if (s + a[i] < b[j]) {s += a[i++];} else {s = b[j++];}}while (i <= n) {s += a[i++];}printf("%lld\n", s);return 0;
}
题解:
1.类型定义
typedef long long l;
typedef long long l;
:将 long long
类型重命名为 l
,后续代码中就可以用 l
来定义长整型变量,让代码更简洁。
2.main
函数及变量声明
int n, m;
:定义两个整型变量 n
和 m
,分别用于存储数组 a
和 b
的长度。
l s = 0;
:定义一个长整型变量 s
并初始化为 0,这个变量用于存储累加结果。
l a[N + 1], b[N + 1];
:定义两个长整型数组 a
和 b
,数组长度为 N + 1
,这样数组的有效下标范围是从 1 到 N
。
int i = 1, j = 1;
:定义两个整型变量 i
和 j
并初始化为 1,它们分别作为数组 a
和 b
的下标,用于遍历数组元素。
3.核心逻辑
while (i <= n && j <= m) {if (s + a[i] < b[j]) {s += a[i++];} else {s = b[j++];}}
while (i <= n && j <= m)
:只要数组 a
和 b
都还有未处理的元素,就会继续执行循环。
if (s + a[i] < b[j])
:如果当前累加结果 s
加上数组 a
的当前元素 a[i]
小于数组 b
的当前元素 b[j]
,就把 a[i]
累加到 s
中,然后 i
加 1,指向下一个 a
数组元素。
else
:否则,将 s
更新为 b[j]
,然后 j
加 1,指向下一个 b
数组元素
4.总结
这段代码的主要逻辑是:依次比较数组 a
和 b
的元素,根据特定规则更新累加结果 s
,直到数组 b
的元素全部处理完,再把数组 a
剩余的元素累加到 s
中,最后输出 s
的值。
题目二:
AC代码 :
#include <stdio.h>#define S 1000005// 模拟队列的结构体
typedef struct {int d[S];int f;int r;
} Q;// 初始化队列
void i(Q *q) {q->f = 0;q->r = 0;
}// 判断队列是否为空
int e(Q *q) {return q->f == q->r;
}// 入队操作
void en(Q *q, int v) {q->d[q->r++] = v;
}// 出队操作
int de(Q *q) {return q->d[q->f++];
}// 获取队首元素
int fr(Q *q) {return q->d[q->f];
}int s[S], a[S];
int n;int main() {Q q;i(&q);// 输入 nscanf("%d", &n);// 先制造一叠牌(1,2,...,n)for (int j = 1; j <= n; j++) {en(&q, j);}// 开始模拟for (int j = 1; !e(&q); j++) {en(&q, fr(&q));de(&q);s[j] = fr(&q);de(&q);}// 将 j 放在 s[j] 处,经过一通操作后,就在正确的位置了for (int j = 1; j <= n; j++) {a[s[j]] = j;}// 输出for (int j = 1; j <= n; j++) {printf("%d ", a[j]);}printf("\n");return 0;
}
题解:
1.队列结构体定义
// 模拟队列的结构体
typedef struct {int d[S];int f;int r;
} Q;
typedef struct
:定义一个结构体类型 Q
来模拟队列。
int d[S]
:一个长度为 S
的整型数组,用于存储队列中的元素。
int f
:表示队列的队首指针,指向队列中第一个元素的位置。
int r
:表示队列的队尾指针,指向队列中下一个可插入元素的位置。
2.队列操作函数
初始化队列
// 初始化队列
void i(Q *q) {q->f = 0;q->r = 0;
}
void i(Q *q)
:该函数用于初始化队列,将队首指针 f
和队尾指针 r
都置为 0,表示队列为空。
判断队列是否为空
// 判断队列是否为空
int e(Q *q) {return q->f == q->r;
}
int e(Q *q)
:该函数用于判断队列是否为空。如果队首指针 f
等于队尾指针 r
,则表示队列为空,返回 1;否则返回 0。
入队操作
// 入队操作
void en(Q *q, int v) {q->d[q->r++] = v;
}
void en(Q *q, int v)
:该函数用于将元素 v
插入到队列中。将元素 v
存储在队列数组 d
的 r
位置,然后将队尾指针 r
加 1。
出队操作
// 出队操作
int de(Q *q) {return q->d[q->f++];
}
int de(Q *q)
:该函数用于从队列中取出队首元素。返回队列数组 d
中 f
位置的元素,然后将队首指针 f
加 1。
获取队首元素
// 获取队首元素
int fr(Q *q) {return q->d[q->f];
}
int fr(Q *q)
:该函数用于获取队列的队首元素,直接返回队列数组 d
中 f
位置的元素。
3.主函数
初始化队列
Q q;
i(&q);
定义一个队列变量 q
,并调用 i
函数对其进行初始化。
构建初始牌堆
// 先制造一叠牌(1,2,...,n)
for (int j = 1; j <= n; j++) {en(&q, j);
}
使用 for
循环将编号从 1 到 n
的扑克牌依次入队,构建初始的牌堆。
模拟扑克牌操作过程
// 开始模拟
for (int j = 1; !e(&q); j++) {en(&q, fr(&q));de(&q);s[j] = fr(&q);de(&q);
}
for (int j = 1; !e(&q); j++)
:只要队列不为空,就持续进行操作。
en(&q, fr(&q));
:将队首元素取出并重新插入到队尾。
de(&q);
:将队首元素出队。
s[j] = fr(&q);
:记录当前队首元素的编号到 s
数组中。
de(&q);
:将队首元素出队。
确定每个位置对应的原始牌编号
// 将 j 放在 s[j] 处,经过一通操作后,就在正确的位置了
for (int j = 1; j <= n; j++) {a[s[j]] = j;
}
通过遍历 s
数组,将 j
存储到 a
数组的 s[j]
位置,从而得到每个位置最终对应的原始牌编号。