第1题:数对
给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍。 比如给定1 4 3 2 9 7 18 22,得到的答案是3,因为2是1的两倍,4是2个两倍,18是9的两倍。
时间限制:1000
内存限制:65536
输入
一行,给出2到15个两两不同且小于100的正整数。最后用0表示输入结束。
输出
一个整数,即有多少个数对满足其中一个数是另一个数的两倍。
样例输入
1 4 3 2 9 7 18 22 0
样例输出
3
以下是使用C语言编写的解决方案:
#include <stdio.h>#define MAX_N 15int main() {int numbers[MAX_N];int n = 0;// 读取输入数据while (1) {scanf("%d", &numbers[n]);if (numbers[n] == 0) {break;}n++;}int count = 0;// 遍历每对数对for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (numbers[i] == numbers[j] * 2) {count++;}}}printf("%d\n", count);return 0;
}
这段代码首先创建一个整数数组numbers来存储输入的正整数。然后,使用一个循环逐个读取输入的正整数,直到遇到输入的结束标志0。同时,通过变量n记录输入的正整数的个数。
接下来,我们使用两个嵌套的循环来遍历每对数对。对于每一对数对 (i, j),我们检查是否满足 numbers[i] == numbers[j] * 2 的条件,如果满足,则将计数器 count 增加1。
最后,输出计数器 count 的值,即满足条件的数对的个数。
第2题:井和绳子
有A, B, C, D, E五家人共用一口井,已知井深不超过k米。A, B, C, D, E的绳长各不相同,而且厘米表示的绳长一定是整数。
从井口放下绳索正好达到水面时:
(a)需要A家的绳n1条接上B家的绳1条
(b)需要B家的绳n2条接上C家的绳1条
©需要C家的绳n3条接上D家的绳1条
(d)需要D家的绳n4条接上E家的绳1条
(e)需要E家的绳n5条接上A家的绳1条
问井深和各家绳长。
时间限制:1000
内存限制:65536
输入
输入只有1行。包括空格分开的6个整数。 第一个整数k(1 <= k <= 20),代表井的最大深度(单位:米)。 接下来是5个正整数n1, n2, n3, n4, n5。这五个整数的含义见上面的题目描述。
输出
输出只有1行。 如果找到了可行解,就输出6个整数,用空格分开,分别代表井的深度和A, B, C, D, E的绳长(单位都是厘米)。 如果有多组可行解,输出井的深度最小的那组解。 如果不存在可行解,就输出一行: not found
样例输入
10 2 3 4 5 6
样例输出
721 265 191 148 129 76
这个问题可以使用暴力穷举的方法来解决。由于井深不超过k米,并且绳长以厘米为单位,我们可以通过遍历所有可能的井深和绳长的组合来找到满足条件的解。
以下是使用C语言编写的解决方案:
#include <stdio.h>int main() {int k, n1, n2, n3, n4, n5;scanf("%d %d %d %d %d %d", &k, &n1, &n2, &n3, &n4, &n5);int found = 0;int minDepth = 1000000; // 初始化最小深度为一个大的数值int bestDepth, bestA, bestB, bestC, bestD, bestE;// 遍历井深for (int depth = 1; depth <= k; depth++) {// 遍历A的绳长for (int a = depth * n2 * n3 * n4 * n5 + 1; a <= depth * n1; a++) {// 遍历B的绳长for (int b = a * n3 * n4 * n5 + 1; b <= a * n2; b++) {// 遍历C的绳长for (int c = b * n4 * n5 + 1; c <= b * n3; c++) {// 遍历D的绳长for (int d = c * n5 + 1; d <= c * n4; d++) {// 遍历E的绳长for (int e = d + 1; e <= d * n5; e++) {// 检查是否满足条件if (e * n1 == depth * n2 * n3 * n4 * n5) {found = 1;// 更新最小深度和最优解if (depth < minDepth) {minDepth = depth;bestDepth = depth;bestA = a;bestB = b;bestC = c;bestD = d;bestE = e;}}}}}}}}if (found) {printf("%d %d %d %d %d %d\n", bestDepth, bestA, bestB, bestC, bestD, bestE);} else {printf("not found\n");}return 0;
}
这段代码首先读取输入的井深k和绳长n1、n2、n3、n4、n5。然后,使用嵌套的循环来遍历所有可能的井深和绳长的组合。
对于每一组井深和绳长的组合,我们计算出A、B、C、D、E的绳长,并检查是否满足给定的条件。如果满足条件,我们更新最小深度和最优解的值。
最后,如果找到了可行解,就输出最优解的井深和A、B、C、D、E的绳长。如果不存在可行解,就输出 “not found”。
第3题:爬楼
已知楼梯的数量,可以每次走2级或者3级,求不同的走法数
例如:楼梯一共有7级,一共3种方法:2 2 3或者 2 3 2 或者 3 2 2。
时间限制:1000
内存限制:65536
输入
输入包含若干行,每行包含一个正整数N,代表楼梯级数,1 <= N <= 50。 最后一行为0,表示测试结束。
输出
不同的走法数,每一行输入对应一行输出
样例输入
7
0
样例输出
3
这个问题可以使用动态规划来解决。我们可以定义一个数组dp,其中dp[i]表示爬到第i级楼梯的不同走法数。初始时,我们将dp[0]设置为1,表示爬到第0级楼梯的方法数为1。
然后,我们可以根据题目中给出的规则进行状态转移。爬到第i级楼梯的方法数等于爬到第i-2级楼梯的方法数加上爬到第i-3级楼梯的方法数。即dp[i] = dp[i-2] + dp[i-3]。
最后,我们遍历输入的楼梯级数,根据dp数组输出对应的不同走法数。
以下是使用C语言编写的解决方案:
#include <stdio.h>#define MAX_N 51int main() {int dp[MAX_N];dp[0] = 1;dp[1] = 0;dp[2] = 1;dp[3] = 1;int n;while (1) {scanf("%d", &n);if (n == 0) {break;}for (int i = 4; i <= n; i++) {dp[i] = dp[i - 2] + dp[i - 3];}printf("%d\n", dp[n]);}return 0;
}
在这段代码中,我们首先定义一个数组dp来存储不同楼梯级数对应的走法数。然后,我们根据题目中给出的初始条件,将dp[0]、dp[1]、dp[2]、dp[3]的值分别设置为1、0、1、1。
接下来,我们通过循环遍历输入的楼梯级数,根据动态规划的状态转移公式dp[i] = dp[i-2] + dp[i-3]计算出不同走法数。最后,输出dp[n],即第n级楼梯的不同走法数。
注意,在这段代码中,我们使用了一个循环来处理多个输入的情况,直到遇到输入的结束标志0。
第4题:表达式求值
输入一个布尔表达式,请你输出它的真假值。
比如:( V | V ) & F & ( F | V )
V表示true,F表示false,&表示与,|表示或,!表示非。
上式的结果是F
时间限制:1000
内存限制:65536
输入
输入包含多行,每行一个布尔表达式,表达式中可以有空格,总长度不超过1000
输出
对每行输入,如果表达式为真,输出"V",否则出来"F"
样例输入
( V | V ) & F & ( F| V)
!V | V & V & !F & (F | V ) & (!F | F | !V & V)
(F&F|V|!V&!F&!(F|F&V))
样例输出
F
V
V
这个问题可以使用递归和逻辑运算符的优先级来解决这个问题。以下是一个解决该问题的C语言代码示例:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>bool evaluateExpression(char* expr, int* index) {bool result = false;bool operand1, operand2;char operator;while (*index < strlen(expr)) {char currentChar = expr[*index];if (currentChar == '(') {(*index)++;operand1 = evaluateExpression(expr, index);} else if (currentChar == 'V' || currentChar == 'F') {operand1 = (currentChar == 'V');(*index)++;} else if (currentChar == '!') {(*index)++;operand1 = !evaluateExpression(expr, index);} else {operator = currentChar;(*index)++;break;}if (operator == '|' && operand1) {result = true;break;} else if (operator == '&' && !operand1) {result = false;break;}}while (*index < strlen(expr)) {char currentChar = expr[*index];if (currentChar == ')') {(*index)++;break;} else if (currentChar == '|' || currentChar == '&') {operator = currentChar;(*index)++;} else {break;}if (operator == '|') {operand2 = evaluateExpression(expr, index);result = result || operand2;} else if (operator == '&') {operand2 = evaluateExpression(expr, index);result = result && operand2;}}return result;
}int main() {char expr[1000];while (fgets(expr, sizeof(expr), stdin)) {if (strcmp(expr, "0\n") == 0) {break;}int index = 0;bool result = evaluateExpression(expr, &index);printf("%c\n", (result ? 'V' : 'F'));}return 0;
}
在这段代码中,我们定义了一个递归函数evaluateExpression
来对布尔表达式进行求值。我们从左到右遍历表达式的字符,根据字符的类型和逻辑运算符的优先级进行求值。
当遇到左括号时,我们递归调用evaluateExpression
函数来求解括号内的子表达式。
当遇到字母V
或F
时,我们将其作为操作数,直接赋值给operand1
。
当遇到!
运算符时,我们递归调用evaluateExpression
函数来求解!
后面的子表达式,并对其求反。
当遇到|
运算符时,如果operand1
为真,则结果为真,否则继续求解后面的子表达式。
当遇到&
运算符时,如果operand1
为假,则结果为假,否则继续求解后面的子表达式。
最后,我们使用printf
函数输出求得的结果。
希望这个简单的解决方法对你有帮助!
第5题:数列
用以下方式构造数列: 数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。
给出一个正整数a,要求数列中第a个数对1000取模的结果是多少。
时间限制:1000
内存限制:65536
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数a(1 <= a <= 1000000)。
输出
n行,每行输出对应一个输入。输出应是一个正整数,为数列中第a个数对1000取模得到的结果。
样例输入
4
5
2
19
1
样例输出
5
1
181
1
你可以使用循环来生成数列,并在生成过程中对每个数进行取模操作,以避免数值溢出。以下是一个解决该问题的C语言代码示例:
#include <stdio.h>int main() {int n;scanf("%d", &n);while (n--) {int a;scanf("%d", &a);int num1 = 1;int num2 = 1;int result = 1;if (a == 1 || a == 2) {printf("%d\n", result);continue;}for (int i = 3; i <= a; i++) {result = (num1 + num2) % 1000;num1 = num2;num2 = result;}printf("%d\n", result);}return 0;
}
在这段代码中,我们首先读取测试数据的组数n,并使用一个循环来处理每组测试数据。
对于每组测试数据,我们读取正整数a,并使用变量num1
和num2
来追踪数列中的前两个数,初始值都为1。
接下来,我们使用一个循环从第3个数开始生成数列。每次迭代,我们计算当前数的值为num1 + num2
,并对结果进行取模操作,以保证结果不会溢出。然后,我们更新num1
和num2
的值,并继续迭代,直到生成到第a个数。
最后,我们输出第a个数对1000取模的结果。
希望这个代码示例能够帮助你解决问题!