一学一做共青团网站成人短期培训学校
C/C++编程(1~8级)全部真题・点这里
第1题:铺砖
对于一个2行N列的走道。现在用12,22的砖去铺满。问有多少种不同的方式。
时间限制:3000
内存限制:131072
输入
整个测试有多组数据,请做到文件底结束。每行给出一个数字N,0 <= n <= 250
输出
如题
样例输入
2
8
12
100
200
样例输出
3
171
2731
845100400152152934331135470251
1071292029505993517027974728227441735014801995855195223534251
下面是一个使用C语言实现的解决方案,可以计算铺砖的不同方式数量:
#include <stdio.h>#define MAX_N 251typedef long long ll;ll dp[MAX_N];// 动态规划求解铺砖的不同方式数量
void calculate_ways() {dp[0] = 1;dp[1] = 1;dp[2] = 3;for (int i = 3; i < MAX_N; i++) {dp[i] = dp[i-1] + 2 * dp[i-2];}
}int main() {calculate_ways();int N;while (scanf("%d", &N) != EOF) {printf("%lld\n", dp[N]);}return 0;
}
这个实现中,我们使用动态规划的思想来计算铺砖的不同方式数量。首先,我们定义一个全局数组dp
,用于存储不同长度走道的铺砖方式数量。然后,我们通过递推关系式dp[i] = dp[i-1] + 2 * dp[i-2]
来计算不同长度走道的铺砖方式数量。
在main
函数中,我们首先调用calculate_ways
函数,计算出所有长度走道的铺砖方式数量。然后,我们循环读取输入的走道长度N
,并输出对应的铺砖方式数量dp[N]
。
注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。此外,题目给出的时间限制较短,因此可以采用动态规划预计算的方式,在实际查询时直接输出结果,而不需要每次都重新计算。
第2题:吃糖果2
现有n(50 > n > 0)个糖果,每天只能吃2个或者3个,请计算共有多少种不同的吃法吃完糖果。
时间限制:1000
内存限制:65536
输入
输入的每一行包括一组测试数据,即为糖果数n。最后一行为0,表示测试结束。
输出
每一行输出对应一行输入的结果,即为吃法的数目。
样例输入
1
2
3
4
12
0
样例输出
0
1
1
1
12
下面是一个使用C语言实现的解决方案,可以计算吃糖果的不同吃法数量:
#include <stdio.h>int count_eating_ways(int n) {if (n < 2) {return 0;}int dp[n + 1];dp[0] = 0;dp[1] = 0;dp[2] = 1;dp[3] = 1;for (int i = 4; i <= n; i++) {dp[i] = dp[i - 2] + dp[i - 3];}return dp[n];
}int main() {int n;while (scanf("%d", &n) == 1 && n != 0) {int ways = count_eating_ways(n);printf("%d\n", ways);}return 0;
}
这个实现中,我们定义了一个辅助函数count_eating_ways
,用于计算吃糖果的不同吃法数量。在函数中,我们使用动态规划的思想来计算,定义一个数组dp
,其中dp[i]
表示吃i
个糖果的不同吃法数量。初始时,我们将dp[0]
和dp[1]
设为0,dp[2]
和dp[3]
设为1。然后,我们通过递推关系式dp[i] = dp[i - 2] + dp[i - 3]
来计算吃i
个糖果的不同吃法数量。
在main
函数中,我们循环读取输入的糖果数量n
,并调用count_eating_ways
函数计算对应的吃法数量。最后,我们输出吃法数量。
注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。
第3题:扩号匹配问题
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$“标注,不能匹配的右括号用”?“标注.
时间限制:3000
内存限制:65536
输入
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100
输出
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由”$“,”?“和空格组成,”$“和”?"表示与之对应的左括号和右括号不能匹配。
样例输入
((ABCD(x)
)(rttyy())sss)(
样例输出
((ABCD(x)
$$
)(rttyy())sss)(
? ?$
下面是一个使用C语言实现的解决方案,可以找到无法匹配的左括号和右括号,并输出标记后的字符串:
#include <stdio.h>
#include <string.h>#define MAX_LENGTH 100void match_parentheses(char* str) {int len = strlen(str);int mismatch[len];memset(mismatch, 0, sizeof(mismatch));int stack[MAX_LENGTH];int top = -1;for (int i = 0; i < len; i++) {if (str[i] == '(') {stack[++top] = i;} else if (str[i] == ')') {if (top == -1) {mismatch[i] = 1;} else {top--;}}}while (top != -1) {mismatch[stack[top--]] = 1;}for (int i = 0; i < len; i++) {if (mismatch[i] == 1) {str[i] = '$';} else if (str[i] == ')') {str[i] = '?';}}
}int main() {char str[MAX_LENGTH];while (fgets(str, MAX_LENGTH, stdin) != NULL) {int len = strlen(str);if (str[len - 1] == '\n') {str[len - 1] = '\0';}match_parentheses(str);printf("%s\n", str);for (int i = 0; i < len; i++) {if (str[i] == '$' || str[i] == '?') {printf("%c", str[i]);} else {printf(" ");}}printf("\n");}return 0;
}
这个实现中,我们定义了一个辅助函数match_parentheses
,用于找到无法匹配的左括号和右括号,并将其标记为'$'
和'?'
。函数中,我们使用一个栈来辅助匹配括号,遍历字符串,当遇到左括号时,将其索引入栈;当遇到右括号时,如果栈为空,则说明没有与之匹配的左括号,将当前右括号标记为无法匹配;否则,将栈顶的左括号出栈,表示匹配成功。最后,将剩余未匹配的左括号标记为无法匹配。
在main
函数中,我们循环读取输入的字符串,并调用match_parentheses
函数对其进行处理。然后,我们先输出原始字符串,再输出标记后的字符串,其中无法匹配的左括号用'$'
表示,无法匹配的右括号用'?'
表示。
注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。
第4题:质数的和与积
两个质数的和是S,它们的积最大是多少?
时间限制:10000
内存限制:65536
输入
一个不大于10000的正整数S,为两个质数的和。
输出
一个整数,为两个质数的最大乘积。数据保证有解。
样例输入
50
样例输出
589
下面是一个使用C语言实现的解决方案,可以找到两个质数的和为给定值S时,它们的最大乘积:
#include <stdio.h>int is_prime(int n) {if (n < 2) {return 0;}for (int i = 2; i * i <= n; i++) {if (n % i == 0) {return 0;}}return 1;
}int find_max_product(int S) {int max_product = 0;for (int i = 2; i <= S / 2; i++) {if (is_prime(i) && is_prime(S - i)) {int product = i * (S - i);if (product > max_product) {max_product = product;}}}return max_product;
}int main() {int S;scanf("%d", &S);int max_product = find_max_product(S);printf("%d\n", max_product);return 0;
}
这个实现中,我们定义了两个辅助函数。is_prime
函数用于判断一个数是否为质数。在函数中,我们首先判断小于2的数不是质数。然后,从2开始遍历到该数的平方根,如果存在能整除该数的因子,说明该数不是质数,否则是质数。
find_max_product
函数用于找到两个质数的和为给定值S时,它们的最大乘积。在函数中,我们从2开始遍历到S的一半,对于每个数i,判断它和S - i是否都是质数。如果是质数,则计算它们的乘积,并与当前的最大乘积比较,更新最大乘积。
在main
函数中,我们读取输入的S,并调用find_max_product
函数找到最大乘积。然后,我们输出最大乘积。
注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。此外,题目保证有解,因此不需要额外处理无解的情况。
第5题:因子问题
任给两个正整数N、M,求一个最小的正整数a,使得a和(M-a)都是N的因子。
时间限制:10000
内存限制:65536
输入
包括两个整数N、M。N不超过1,000,000。
输出
输出一个整数a,表示结果。如果某个案例中满足条件的正整数不存在,则在对应行输出-1
样例输入
35 10
样例输出
5
下面是一个使用C语言实现的解决方案,可以找到满足条件的最小正整数a:
#include <stdio.h>int find_smallest_factor(int N, int M) {for (int a = 1; a <= N; a++) {if (N % a == 0 && (M - a) % N == 0) {return a;}}return -1;
}int main() {int N, M;scanf("%d %d", &N, &M);int smallest_factor = find_smallest_factor(N, M);printf("%d\n", smallest_factor);return 0;
}
这个实现中,我们定义了一个辅助函数find_smallest_factor
,用于找到满足条件的最小正整数a。在函数中,我们从1开始遍历到N,对于每个数a,判断是否同时满足两个条件:N能整除a,且(M - a)能整除N。如果满足条件,则返回a作为最小正整数;如果遍历完所有可能的a都不满足条件,则返回-1。
在main
函数中,我们读取输入的N和M,并调用find_smallest_factor
函数找到最小正整数a。然后,我们输出a。
注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。