C/C++编程(1~8级)全部真题・点这里
Python编程(1~6级)全部真题・点这里
“臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男,你发现自己与他人相互了解的机会并不太多。幸运的是,你意外得到了一份北大图书馆的图书借阅记录,于是你挑灯熬夜地编程,想从中发现潜在的朋友。 首先你对借阅记录进行了一番整理,把N个读者依次编号为1,2,…,N,把M本书依次编号为1,2,…,M。同时,按照“臭味相投”的原则,和你喜欢读同一本书的人,就是你的潜在朋友。你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。
时间限制:1000
内存限制:65536
输入
第一行两个整数N,M,2 <= N ,M<= 200。接下来有N行,第i(i = 1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)
输出
包括N行,每行一个数,第i行的数表示读者i有几个潜在朋友。如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^ ^)
样例输入
4 5
2
3
2
1
样例输出
1
BeiJu
1
BeiJu
以下是使用C语言编写的计算每个人有几个潜在朋友的程序:
#include
int main() {
int N, M;
scanf("%d %d", &N, &M);
int books[M]; // 用于记录每本书被喜欢的次数,下标表示书的编号
int friends[N]; // 用于记录每个人有几个潜在朋友,下标表示人的编号
// 初始化数组
for (int i = 0; i < M; i++) {
books[i] = 0;
}
for (int i = 0; i < N; i++) {
int book;
scanf("%d", &book);
friends[i] = 0; // 初始化每个人的潜在朋友数为0
books[book - 1]++; // 喜欢该书的人数加1
}
// 计算每个人的潜在朋友数
for (int i = 0; i < N; i++) {
int book = friends[i];
if (books[book - 1] == 1) {
friends[i] = 0; // 没有共同喜欢的书,潜在朋友数为0
} else {
friends[i] = books[book - 1] - 1; // 共同喜欢的人数减1为潜在朋友数
}
}
// 输出每个人的潜在朋友数
for (int i = 0; i < N; i++) {
if (friends[i] == 0) {
printf("BeiJu\n");
} else {
printf("%d\n", friends[i]);
}
}
return 0;
}
程序首先使用scanf
函数从标准输入读取读者数量N
和图书数量M
。
然后,定义一个大小为M
的整数数组books
,用于记录每本书被喜欢的次数。定义一个大小为N
的整数数组friends
,用于记录每个人有几个潜在朋友。数组下标表示人的编号和书的编号。
接下来,使用循环初始化books
数组为0。
然后,使用循环依次读取每个人最喜欢的图书编号,并将对应的books
数组的元素加1。
接下来,使用另一个循环计算每个人的潜在朋友数。如果一个人喜欢的书只有他一个人喜欢,表示没有共同喜欢的书,潜在朋友数为0。否则,共同喜欢的人数减1为潜在朋友数。
最后,使用printf
函数输出每个人的潜在朋友数。如果潜在朋友数为0,则输出"BeiJu",否则输出具体的潜在朋友数。
例如,如果输入为4 5
和以下读者喜欢的图书编号数据:
2
3
2
1
则程序将计算每个人的潜在朋友数,并输出到标准输出。根据给定的数据,读者1和读者3没有共同喜欢的书,潜在朋友数为0,输出"BeiJu"。读者2和读者4共同喜欢图书2,潜在朋友数为1,输出"1"。
小 A 修了 n 门课程, 第 i 门课程是从第 ai 天一直上到第 bi 天。
定义两门课程的冲突程度为 : 有几天是这两门课程都要上的。
例如 a1=1,b1=3,a2=2,b2=4 时, 这两门课的冲突程度为 2。
现在你需要求的是这 n 门课中冲突程度最大的两门课的冲突程度。
时间限制:1000
内存限制:65536
输入
第一行一个正整数 n 表示课程数量。 接下来 n 行,每行两个正整数 ai,bi。 2 ≤ n≤ 1000, 1 ≤ ai ≤ bi ≤ 1000。
输出
输出一个整数表示最大的冲突程度
样例输入
3
1 3
2 4
5 5
样例输出
2
以下是使用C语言编写的计算课程冲突程度的程序:
#include
int main() {
int n;
scanf("%d", &n);
int courses[n][2]; // 二维数组存储课程的起始和结束时间
// 读取课程的起始和结束时间
for (int i = 0; i < n; i++) {
scanf("%d %d", &courses[i][0], &courses[i][1]);
}
int maxConflict = 0; // 最大冲突程度
// 计算冲突程度
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int conflict = 0; // 冲突程度
// 判断两门课程的冲突天数
for (int day = courses[i][0]; day <= courses[i][1]; day++) {
if (day >= courses[j][0] && day <= courses[j][1]) {
conflict++;
}
}
// 更新最大冲突程度
if (conflict > maxConflict) {
maxConflict = conflict;
}
}
}
printf("%d\n", maxConflict);
return 0;
}
程序首先使用scanf
函数从标准输入读取课程数量n
。
然后,定义一个二维数组courses
,用于存储每门课程的起始和结束时间。数组的行数为课程数量n
,每一行有两列,第一列存储起始时间,第二列存储结束时间。
接下来,使用循环依次读取每门课程的起始和结束时间,并将其存储在courses
数组中。
然后,定义一个变量maxConflict
,用于记录最大冲突程度,初始化为0。
使用两层循环遍历所有可能的课程组合,计算每对课程的冲突程度。
在内层循环中,使用一个变量conflict
初始化为0,表示两门课程的冲突程度。然后,使用一个循环遍历两门课程之间的所有天数,并判断是否存在冲突。如果某天既是第一门课程的上课时间也是第二门课程的上课时间,则冲突程度加1。
在外层循环中,更新最大冲突程度maxConflict
,如果当前的冲突程度大于最大冲突程度,则更新maxConflict
的值。
最后,使用printf
函数输出最大冲突程度。
例如,如果输入为3
和以下课程的起始和结束时间数据:
1 3
2 4
5 5
则程序将计算每对课程的冲突程度,并输出最大冲突程度。根据给定的数据,第一门课程和第二门课程的冲突程度为2,第一门课程和第三门课程的冲突程度为0,第二门课程和第三门课程的冲突程度为0。因此,最大冲突程度为2,输出"2"。
有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:
a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b. 走过的格子立即塌陷无法再走第二次;
c. 只能向北、东、西三个方向走;
请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同的方案。
时间限制:1000
内存限制:65536
输入
允许在方格上行走的步数n(n <= 20)
输出
计算出的方案数量
样例输入
2
样例输出
7
这是一个经典的组合计数问题,可以使用动态规划来解决。以下是使用C语言编写的计算方案数量的程序:
#include
int main() {
int n;
scanf("%d", &n);
// 创建一个二维数组dp,用于存储每个位置上走n步的方案数量
int dp[n+1][3];
// 初始化dp数组
for (int i = 0; i <= n; i++) {
for (int j = 0; j < 3; j++) {
dp[i][j] = 0;
}
}
// 设置初始条件
dp[0][0] = 1; // 起始位置,步数为0,方案数为1
// 计算方案数量
for (int step = 1; step <= n; step++) {
// 递推公式
dp[step][0] = dp[step-1][0] + dp[step-1][1] + dp[step-1][2];
dp[step][1] = dp[step-1][0] + dp[step-1][2];
dp[step][2] = dp[step-1][0] + dp[step-1][1];
}
// 计算总方案数量
int total = dp[n][0] + dp[n][1] + dp[n][2];
printf("%d\n", total);
return 0;
}
程序首先使用scanf
函数从标准输入读取允许在方格上行走的步数n
。
然后,创建一个二维数组dp
,用于存储每个位置上走n步的方案数量。数组的行数为n+1
,列数为3。第一列表示当前位置向北走的方案数量,第二列表示向东走的方案数量,第三列表示向西走的方案数量。
接下来,使用嵌套循环初始化dp
数组为0。
然后,设置初始条件,将起始位置的方案数量设置为1,即dp[0][0] = 1
。
使用一个循环计算方案数量,从步数1到n。
在循环中,根据递推公式计算每个位置上的方案数量。例如,dp[step][0]
表示在第step步时,当前位置向北走的方案数量,可以从前一步的三个方向的方案数量累加得到。
最后,计算总方案数量,即将三个方向的方案数量相加。
最后,使用printf
函数输出总方案数量。
例如,如果输入为2
,表示允许在方格上走2步,则程序将计算总方案数量,并输出结果。根据给定的数据,总方案数量为7,输出"7"。
医院为了方便对患者进行建档和管理,引入了9位整数ID号来标识每个病人。最近医院入住了一个迷信的病人,他认为ID号的好坏直接决定了自己的命运。他对ID号x有如下要求:
(1)x的前三位数构成的整数是素数
(2)x的后三位数构成的整数是平方数(所谓平方数,是指它是某一个正整数的平方,e.g. 1,4,9,16…)
(3)x中不包含"13"
为了避免不必要的医患矛盾,医院须尽量满足他的需求。现给定正整数区间[m,n],请你判断存在几个满足病人需求的ID号。
时间限制:1000
内存限制:65536
输入
两个正整数m,n,以空格隔开。(999999999>=n>=m>=111111111)
输出
一个整数(满足要求的ID的个数)。
样例输入
157689476 157689687
样例输出
5
提示
存在5个满足要求的ID:157689484,157689529,157689576,157689625,157689676
这个问题可以通过遍历给定的区间[m, n],对每个数字进行判断是否满足迷信病人的要求。以下是使用C语言编写的判断满足要求的ID号个数的程序:
#include
#include
// 判断一个数字是否为素数
int isPrime(int num) {
if (num < 2) {
return 0;
}
for (int i = 2; i <= sqrt(num); i++) {
if (num % i == 0) {
return 0;
}
}
return 1;
}
// 判断一个数字是否为平方数
int isSquare(int num) {
int root = sqrt(num);
return (root * root == num);
}
// 判断一个数字是否包含13
int hasThirteen(int num) {
while (num > 0) {
if (num % 100 == 13) {
return 1;
}
num /= 10;
}
return 0;
}
int main() {
int m, n;
scanf("%d %d", &m, &n);
int count = 0; // 满足要求的ID号个数
// 遍历区间[m, n],判断每个数字是否满足要求
for (int num = m; num <= n; num++) {
int firstThreeDigits = num / 1000; // 前三位数
int lastThreeDigits = num % 1000; // 后三位数
if (isPrime(firstThreeDigits) && isSquare(lastThreeDigits) && !hasThirteen(num)) {
count++;
}
}
printf("%d\n", count);
return 0;
}
程序首先使用scanf
函数从标准输入读取正整数区间[m, n]。
然后,定义一个变量count
,用于存储满足要求的ID号个数,初始化为0。
使用一个循环遍历区间[m, n],对每个数字进行判断。
在循环中,首先将当前数字拆分为前三位数和后三位数。
然后,使用三个辅助函数isPrime
、isSquare
和hasThirteen
进行判断。
isPrime
函数判断前三位数是否为素数,通过从2到sqrt(num)的范围内判断是否有因子。
isSquare
函数判断后三位数是否为平方数,通过计算平方根并判断平方根的平方是否等于后三位数。
hasThirteen
函数判断整个数字是否包含13,通过循环依次取出两位数字并判断是否为13。
如果前三位数是素数,后三位数是平方数,且整个数字不包含13,则将满足要求的ID号个数加1。
最后,使用printf
函数输出满足要求的ID号个数。
例如,如果输入为157689476 157689687
,表示正整数区间为[157689476, 157689687],则程序将判断每个数字是否满足要求,并输出满足要求的ID号个数。根据给定的数据,存在5个满足要求的ID号,输出"5"。
Pell数列a1, a2, a3, …的定义是这样的,a1 = 1, a2 = 2, … , an = 2 * an − 1 + an - 2 (n > 2)。 给出一个正整数k,要求Pell数列的第k项模上32767是多少。
时间限制:3000
内存限制:65536
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数k (1 ≤ k < 1000000)。
输出
n行,每行输出对应一个输入。输出应是一个非负整数。
样例输入
2
1
8
样例输出
1
408
这个问题可以使用循环来计算Pell数列的第k项,并对结果取模。以下是使用C语言编写的计算Pell数列的第k项模32767的程序:
#include
int pellModulo(int k) {
int a1 = 1; // 第1项
int a2 = 2; // 第2项
int ak; // 第k项
if (k == 1) {
return a1 % 32767;
} else if (k == 2) {
return a2 % 32767;
}
for (int i = 3; i <= k; i++) {
ak = (2 * a2 + a1) % 32767;
a1 = a2;
a2 = ak;
}
return ak;
}
int main() {
int n;
scanf("%d", &n);
while (n--) {
int k;
scanf("%d", &k);
int result = pellModulo(k);
printf("%d\n", result);
}
return 0;
}
程序首先使用scanf
函数从标准输入读取测试数据的组数n。
然后,使用一个循环处理每组测试数据。
在循环中,使用scanf
函数从标准输入读取一个正整数k,表示Pell数列的第k项。
调用pellModulo
函数计算Pell数列的第k项模32767的结果。
在pellModulo
函数中,使用三个变量a1
、a2
和ak
来保存Pell数列的第1项、第2项和第k项。
根据题目给出的递推公式,使用一个循环从第3项开始计算第k项:ak = 2 * a2 + a1
。
在每次迭代中,更新a1
和a2
的值,将a2
赋给a1
,将ak
赋给a2
,以便在下一次迭代中使用。
最后,将计算得到的第k项模32767的结果返回。
在主函数中,将计算得到的结果使用printf
函数输出。
例如,如果输入为2
,表示有两组测试数据,然后依次输入1
和8
。
程序将分别计算Pell数列的第1项和第8项模32767的结果,并输出。
根据给定的数据,第1项模32767的结果为1,输出"1"。
第8项模32767的结果为408,输出"408"。