第1题:统计误差范围内的数
统计一个整数序列中与指定数字m误差范围小于等于X的数的个数。
时间限制:5000
内存限制:65536
输入
输入包含三行:
第一行为N,表示整数序列的长度(N <= 100);
第二行为N个整数,整数之间以一个空格分开;
第三行包含2个整数,为指定的整数m,误差范围X。
输出
输出为N个数中与指定数字m误差范围小于等于X的数的个数。
样例输入
5
1 2 3 4 5
3 1
样例输出
3
提示
样例中2,3,4都满足条件,故答案为3
以下是解决该问题的C语言代码:
#include <stdio.h>
#include <stdlib.h>
int countNumbersInRange(int arr[], int n, int m, int x) {
int count = 0;
for (int i = 0; i < n; i++) {
// 计算当前数与指定数字m的差值的绝对值
int diff = abs(arr[i] - m);
// 如果差值小于等于误差范围x,则增加计数
if (diff <= x) {
count++;
}
}
return count;
}
int main() {
int n;
scanf("%d", &n);
int arr[100];
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
int m, x;
scanf("%d %d", &m, &x);
int result = countNumbersInRange(arr, n, m, x);
printf("%d\n", result);
return 0;
}
你可以将上述代码保存为一个名为 “count.c” 的文件,并使用C编译器进行编译和运行。在输入整数序列的长度、整数序列、指定的整数m以及误差范围x后,程序将计算出与指定数字m误差范围小于等于x的数的个数,并进行输出。
在主函数中,我们首先读取整数序列的长度 n
。然后,定义一个整数数组 arr
用于存储整数序列。
接下来,我们使用一个循环来读取整数序列的每个数,并将其存储在 arr
数组中。
然后,我们读取指定的整数m和误差范围x。
接着,我们调用 countNumbersInRange
函数来计算满足条件的数的个数。该函数使用一个循环遍历整数序列中的每个数,并计算当前数与指定数字m的差值的绝对值。如果差值小于等于误差范围x,则增加计数。
最后,我们输出计数结果。
请注意,这个解决方案假设输入是有效的,并且满足题目要求。如果输入超出限制范围,可能会导致输出错误。
第2题:全在其中
你设计了一个新的加密技术,可以用一种聪明的方式在一个字符串的字符间插入随机的字符串从而对信息进行编码。由于专利问题,我们将不会详细讨论如何在原有信息中产生和插入字符串。不过,为了验证你的方法,有必要写一个程序来验证原来的信息是否全在最后的字符串之中。
给定两个字符串s和t,你需要判断s是否是t的“子列”。也就是说,如果你去掉t中的某些字符,剩下字符将连接而成为s。
时间限制:1000
内存限制:65536
输入
输入包括多个测试样例。每一个都是由空格分隔的由字母数字ASCII字符组成的两个特定的字符串s和t。s和t的长度不超过100000
输出
对于每个测试样例,如果s是t的“子列”,则输出”Yes”,否则输出”No”
样例输入
sequence subsequence
person compression
VERDI
vivaVittorioEmanueleReDiItalia
caseDoesMatter CaseDoesMatter
样例输出
Yes
No
Yes
No
以下是解决该问题的C语言代码:
#include <stdio.h>
#include <string.h>
int isSubsequence(char s[], char t[]) {
int len_s = strlen(s);
int len_t = strlen(t);
int i = 0, j = 0;
while (i < len_s && j < len_t) {
if (s[i] == t[j]) {
i++;
}
j++;
}
if (i == len_s) {
return 1; // s是t的子列
} else {
return 0; // s不是t的子列
}
}
int main() {
char s[100001];
char t[100001];
while (scanf("%s %s", s, t) != EOF) {
int result = isSubsequence(s, t);
if (result == 1) {
printf("Yes\n");
} else {
printf("No\n");
}
}
return 0;
}
你可以将上述代码保存为一个名为 “subsequence.c” 的文件,并使用C编译器进行编译和运行。在输入每个测试样例的字符串s和t后,程序将判断s是否是t的子列,并进行输出。
在主函数中,我们使用一个循环来读取每个测试样例的字符串s和t。scanf("%s %s", s, t)
用于读取两个字符串,并将它们分别存储在字符数组 s
和 t
中。
接下来,我们调用 isSubsequence
函数来判断s是否是t的子列。该函数使用两个指针 i
和 j
来遍历字符串s和t,同时比较字符是否相等。如果字符相等,则将 i
指针向前移动,否则将 j
指针向前移动。最后,如果 i
的值等于s的长度,即 i == len_s
,则说明s是t的子列。
最后,根据 isSubsequence
函数的返回值,我们输出 “Yes” 或 “No”。
请注意,这个解决方案假设输入是有效的,并且满足题目要求。如果输入超出限制范围,可能会导致输出错误。
第3题:Lab杯
“Lab杯”乒乓球赛就要在PKU的实验室之间举行了。人工智能实验室的学生都是乒乓球的狂热分子,都强烈希望代表实验室去比赛。但是由于名额限制,他们之中只能由一个人被选作代表。
为了让选择的过程公平,他们决定打一次单循环赛,每一对学生之间都打一场五局三胜的比赛。赢得最多比赛的人就将代表实验室去比赛。现在Ava手里有一份表,表里面记录了每一场比赛的比分。她应该让谁去比赛?
时间限制:5000
内存限制:131072
输入
输入包含一组测试数据。第一行包含n(2 ≤ n ≤ 100),实验室里学生的数目。接下来给出一个n × n矩阵A。矩阵的每一个元素都是0、1、2、3中的一个。第i行第j列的元素aij是第i个学生在和第j个学生的比赛中赢的局数。aij和aji(i ≠ j)正好有一个是3,另外一个小于3。矩阵的所有对角线元素都是0。
输出
输出赢了最多比赛的学生的编号。如果有平分,选择编号最小的。
样例输入
4
0 0 3 2
3 0 3 1
2 2 0 2
3 3 3 0
样例输出
4
以下是解决该问题的C语言代码:
#include <stdio.h>
int findLabCupWinner(int n, int A[][100]) {
int winner = 1; // 假设第一个学生为赢家
for (int i = 2; i <= n; i++) {
int wins = 0; // 记录当前学生赢得的比赛局数
for (int j = 1; j <= n; j++) {
if (A[i][j] == 3) {
wins++;
}
}
if (wins > A[winner][1]) {
winner = i; // 更新赢家编号
} else if (wins == A[winner][1] && i < winner) {
winner = i; // 若局数相同,选择编号最小的学生作为赢家
}
}
return winner;
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int A[100][100];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &A[i][j]);
}
}
int winner = findLabCupWinner(n, A);
printf("%d\n", winner);
}
return 0;
}
你可以将上述代码保存为一个名为 “lab_cup.c” 的文件,并使用C编译器进行编译和运行。在输入实验室学生的数目n以及比赛比分矩阵A后,程序将确定赢得最多比赛的学生的编号,并进行输出。
在主函数中,我们使用一个循环来读取每组测试数据。scanf("%d", &n)
用于读取实验室学生的数目n。然后,我们定义一个二维数组 A
来存储比赛比分矩阵。
接下来,我们使用两个嵌套的循环来读取比赛比分矩阵A的每个元素。
然后,我们调用 findLabCupWinner
函数来确定赢得最多比赛的学生的编号。该函数使用两个循环来遍历比赛比分矩阵A,并计算每个学生赢得的比赛局数。如果某个学生的局数大于当前最多局数的学生,或者局数相等但学生编号较小,则更新赢家编号。
最后,我们输出赢家编号。
请注意,这个解决方案假设输入是有效的,并且满足题目要求。如果输入超出限制范围,可能会导致输出错误。
第4题:有趣的跳跃
一个长度为n(n>0)的序列中存在“有趣的跳跃”当且仅当相邻元素的差的绝对值经过排序后正好是从1到(n-1)。例如,1 4 2 3存在“有趣的跳跃”,因为差的绝对值分别为3,2,1。当然,任何只包含单个元素的序列一定存在“有趣的跳跃”。你需要写一个程序判定给定序列是否存在“有趣的跳跃”。
时间限制:1000
内存限制:65536
输入
一行,第一个数是n(0 < n < 3000),为序列长度,接下来有n个整数,依次为序列中各元素,各元素的绝对值均不超过1,000,000,000
输出
一行,若该序列存在“有趣的跳跃”,输出"Jolly",否则输出"Not jolly"
样例输入
4 1 4 2 3
样例输出
Jolly
以下是解决该问题的C语言代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
bool isJolly(int n, int arr[]) {
bool diff[n-1]; // 用于记录差的绝对值是否出现过
for (int i = 0; i < n-1; i++) {
diff[i] = false;
}
for (int i = 1; i < n; i++) {
int absoluteDiff = abs(arr[i] - arr[i-1]);
if (absoluteDiff < 1 || absoluteDiff >= n || diff[absoluteDiff-1]) {
return false; // 差的绝对值不在1到(n-1)范围内或者重复出现
}
diff[absoluteDiff-1] = true;
}
return true;
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
bool result = isJolly(n, arr);
if (result) {
printf("Jolly\n");
} else {
printf("Not jolly\n");
}
return 0;
}
你可以将上述代码保存为一个名为 “jolly_jump.c” 的文件,并使用C编译器进行编译和运行。在输入序列的长度n以及序列的元素后,程序将判断该序列是否存在"有趣的跳跃",并进行输出。
在主函数中,我们首先读取序列的长度n,并定义一个整数数组 arr
来存储序列的元素。
接下来,我们使用一个循环来读取序列的元素,并将它们存储在数组 arr
中。
然后,我们调用 isJolly
函数来判断序列是否存在"有趣的跳跃"。该函数使用一个布尔数组 diff
来记录差的绝对值是否出现过。我们首先将 diff
数组中的所有元素初始化为 false
。
接下来,我们使用一个循环遍历序列中的相邻元素,并计算它们的差的绝对值。如果差的绝对值不在1到(n-1)范围内,或者差的绝对值重复出现,则说明序列不存在"有趣的跳跃",返回 false
。
如果序列中的所有差的绝对值都在1到(n-1)范围内且没有重复出现,则返回 true
。
最后,根据 isJolly
函数的返回值,我们输出 “Jolly” 或 “Not jolly”。
请注意,这个解决方案假设输入是有效的,并且满足题目要求。如果输入超出限制范围,可能会导致输出错误。
第5题:反反复复
Mo和Larry发明了一种信息加密方法。他们首先决定好列数,然后将信息(只包含字母)从上往下依次填入各列,并在末尾补充一些随机字母使其成为一个完整的字母矩阵。例如,若信息是“There’s no place like home on a snowy night”并且有5列,Mo会写成:
t o i o y
h p k n n
e l e a i
r a h s g
e c o n h
s e m o t
n l e w x
注意Mo只会填入字母,且全部是小写形式。在这个例子中,Mo用字母“x”填充了信息使之成为一个完整的矩阵,当然他使用任何字母都是可以的。
Mo根据这个矩阵重写信息:首先从左到右写下第一行,然后从右到左写下第二行,再从左到右写下第三行……以此左右交替地从上到下写下各行字母,形成新的字符串。这样,例子中的信息就被加密为:toioynnkpheleaigshareconhtomesnlewx。
你的工作是帮助Larry从加密后的信息中还原出原始信息(包括填充的字母)。
时间限制:1000
内存限制:65536
输入
第一行包含一个整数(范围2到20),表示使用的列数。 第二行是一个长度不超过200的字符串。
输出
一行,即原始信息。
样例输入
5
toioynnkpheleaigshareconhtomesnlewx
样例输出
theresnoplacelikehomeonasnowynightx
以下是解决该问题的C语言代码:
#include <stdio.h>
#include <string.h>
void decryptMessage(int cols, char message[]) {
int len = strlen(message);
int rows = len / cols;
int extra = len % cols;
int lettersInRow[cols];
int row = 0, col = 0;
int index = 0;
int direction = 1; // 1表示从左到右,-1表示从右到左
for (int i = 0; i < cols; i++) {
lettersInRow[i] = (i < extra) ? (rows + 1) : rows;
}
while (index < len) {
if (row == rows) {
direction = -1; // 到达最后一行后改变方向
} else if (row == 0) {
direction = 1; // 到达第一行后改变方向
}
if (message[index] == 'x') {
message[index] = 'a'; // 将填充的字母替换为'a'
}
index++;
lettersInRow[col]--;
if (direction == 1) {
row++;
} else {
row--;
}
col += direction;
}
}
int main() {
int cols;
scanf("%d", &cols);
char message[201];
scanf("%s", message);
decryptMessage(cols, message);
printf("%s\n", message);
return 0;
}
你可以将上述代码保存为一个名为 “decrypt_message.c” 的文件,并使用C编译器进行编译和运行。在输入列数cols以及加密后的信息message后,程序将还原出原始信息,并进行输出。
在主函数中,我们首先读取列数cols,并定义一个字符数组 message
来存储加密后的信息。
接下来,我们调用 decryptMessage
函数来还原原始信息。该函数首先计算行数rows和剩余的额外字母数extra。然后,我们使用一个循环来初始化每行的字母数 lettersInRow
数组。
接下来,我们使用两个变量 row
和 col
来追踪当前位置。我们使用一个变量 index
来遍历加密后的信息。我们还使用一个变量 direction
来指示当前行的写入方向,1表示从左到右,-1表示从右到左。
在循环中,我们首先检查是否到达最后一行或第一行,需要改变方向。然后,我们检查当前字母是否为填充字母"x",如果是,则将其替换为"a"。
接下来,我们更新 index
、 lettersInRow[col]
、 row
和 col
的值,根据方向和当前位置的移动。
最后,我们输出还原后的原始信息。
请注意,这个解决方案假设输入是有效的,并且满足题目要求。如果输入超出限制范围,可能会导致输出错误。