第1题:和数
给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = 2 + 1, 4 = 1 + 3。
时间限制:10000
内存限制:65536
输入
共两行,第一行是数列中数的个数n ( 1 <= n <= 100),第二行是由n个不大于10000的正整数组成的数列,相邻两个整数之间用单个空格隔开。
输出
一个整数,即数列中等于其他两个数之和的数的个数。
样例输入
4
1 2 3 4
样例输出
2
要解决这个问题,我们可以使用两层循环来遍历数列中的元素,并在内层循环中检查当前元素是否等于其他两个元素的和。如果是,则将计数器加1。
下面是使用C语言编写的解题代码:
#include <stdio.h>int main() {int n;scanf("%d", &n);int arr[100];for (int i = 0; i < n; i++) {scanf("%d", &arr[i]);}int count = 0;for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {for (int k = 0; k < n; k++) {if (k != i && k != j && arr[k] == arr[i] + arr[j]) {count++;break;}}}}printf("%d\n", count);return 0;
}
在上述代码中,我们首先读取输入的数列长度 n
,然后读取数列中的元素并存储在数组 arr
中。
接下来,我们使用两层循环来遍历数列中的元素。外层循环控制第一个相加的数 arr[i]
,内层循环控制第二个相加的数 arr[j]
,其中 j
从 i+1
开始以避免重复计算。在内层循环中,我们使用另一个循环遍历数列中的元素 arr[k]
,并检查是否存在一个不等于 arr[i]
和 arr[j]
的元素等于它们的和 arr[i] + arr[j]
。如果存在,则将计数器 count
加1,并跳出内层循环。
最后,我们输出计数器 count
的值作为结果。
编译并运行上述代码可以解决该问题。你可以使用 C 语言编译器将代码保存为 .c
文件,然后编译并运行该文件来获取结果。
第2题:质数的和与积
两个质数的和是S,它们的积最大是多少?
时间限制:10000
内存限制:65536
输入
一个不大于10000的正整数S,为两个质数的和。
输出
一个整数,为两个质数的最大乘积。数据保证有解。
样例输入
50
样例输出
589
要解决这个问题,我们可以使用一个函数来判断一个数是否为质数。然后,我们可以从S开始递减,找到最大的两个质数使它们的和等于S,并计算它们的乘积。
下面是使用C语言编写的解题代码:
#include <stdio.h>
#include <stdbool.h>bool isPrime(int num) {if (num <= 1) {return false;}for (int i = 2; i * i <= num; i++) {if (num % i == 0) {return false;}}return true;
}int main() {int S;scanf("%d", &S);int maxProduct = 0;for (int i = S / 2; i >= 2; i--) {if (isPrime(i) && isPrime(S - i)) {maxProduct = i * (S - i);break;}}printf("%d\n", maxProduct);return 0;
}
在上述代码中,我们首先定义了一个函数 isPrime
来判断一个数是否为质数。该函数接收一个正整数 num
,如果 num
小于等于1,则返回 false
。否则,我们使用一个循环从2开始遍历到 num
的平方根,检查是否存在一个数能整除 num
。如果存在,则 num
不是质数,返回 false
。如果循环结束后仍未找到可以整除 num
的数,则 num
是质数,返回 true
。
在主函数中,我们首先读取输入的和 S
,然后从 S/2
开始递减到2。在每次迭代中,我们检查当前数 i
是否为质数,并且 S - i
也是质数。如果满足条件,则计算 i
和 S - i
的乘积,并将其赋值给 maxProduct
。然后跳出循环。
最后,我们输出 maxProduct
的值作为结果。
编译并运行上述代码可以解决该问题。你可以使用 C 语言编译器将代码保存为 .c
文件,然后编译并运行该文件来获取结果。
第3题:爬楼
已知楼梯的数量,可以每次走2级或者3级,求不同的走法数
例如:楼梯一共有7级,一共3种方法:2 2 3或者 2 3 2 或者 3 2 2。
时间限制:1000
内存限制:65536
输入
输入包含若干行,每行包含一个正整数N,代表楼梯级数,1 <= N <= 50。 最后一行为0,表示测试结束。
输出
不同的走法数,每一行输入对应一行输出
样例输入
7
0
样例输出
3
要解决这个问题,我们可以使用递归来计算不同的走法数。每次递归,我们可以选择走2级或3级,直到达到目标楼梯级数。
下面是使用C语言编写的解题代码:
#include <stdio.h>int countWays(int n) {if (n == 0 || n == 1) {return 1;} else if (n == 2) {return 2;} else if (n == 3) {return 3;} else {return countWays(n - 2) + countWays(n - 3);}
}int main() {int N;while (1) {scanf("%d", &N);if (N == 0) {break;}int ways = countWays(N);printf("%d\n", ways);}return 0;
}
在上述代码中,我们定义了一个递归函数 countWays
来计算不同的走法数。该函数接收一个参数 n
,代表当前楼梯级数。如果 n
为0或1,表示已经到达目标楼梯,返回1。如果 n
为2,表示剩余2级楼梯可以走2次,返回2。如果 n
为3,表示剩余3级楼梯可以走3次,返回3。否则,我们可以选择先走2级楼梯,然后递归计算剩余 n-2
级楼梯的走法数,或者选择先走3级楼梯,然后递归计算剩余 n-3
级楼梯的走法数。最后,将两种情况的走法数相加作为结果返回。
在主函数中,我们使用一个循环来读取输入的楼梯级数 N
,如果 N
为0,则表示测试结束,跳出循环。否则,我们调用 countWays
函数计算不同的走法数,并将结果输出。
编译并运行上述代码可以解决该问题。你可以使用 C 语言编译器将代码保存为 .c
文件,然后编译并运行该文件来获取结果。
第4题:生成括号
Paul是一名数学专业的同学,在课余选修了C++编程课,现在他能够自己写程序判断判断一个给定的由’(‘和’)'组成的字符串是否是正确匹配的。可是他不满足于此,想反其道而行之,设计一个程序,能够生成所有合法的括号组合,请你帮助他解决这个问题。
时间限制:1000
内存限制:65536
输入
输入只有一行N,代表生成括号的对数(1 ≤ N ≤ 10)。
输出
输出所有可能的并且有效的括号组合,按照字典序进行排列,每个组合占一行。
样例输入
3
样例输出
((()))
(()())
(())()
()(())
()()()
要解决这个问题,我们可以使用递归来生成所有合法的括号组合。每次递归,我们可以选择放置一个左括号或右括号,但需要满足以下条件:左括号的数量不能超过N,右括号的数量不能超过左括号的数量。
下面是使用C语言编写的解题代码:
#include <stdio.h>void generateParentheses(int leftCount, int rightCount, int n, char* current, int index) {if (leftCount == n && rightCount == n) {current[index] = '\0';printf("%s\n", current);return;}if (leftCount < n) {current[index] = '(';generateParentheses(leftCount + 1, rightCount, n, current, index + 1);}if (rightCount < leftCount) {current[index] = ')';generateParentheses(leftCount, rightCount + 1, n, current, index + 1);}
}int main() {int N;scanf("%d", &N);char parentheses[20];generateParentheses(0, 0, N, parentheses, 0);return 0;
}
在上述代码中,我们定义了一个递归函数 generateParentheses
来生成所有合法的括号组合。该函数接收五个参数:leftCount
表示当前已放置的左括号的数量,rightCount
表示当前已放置的右括号的数量,n
表示括号的对数,current
是一个字符数组,用于存储当前的括号组合,index
表示当前要放置括号的位置。
在递归函数中,我们首先判断是否已经放置了 n
对括号(即左括号数量和右括号数量都等于 n
)。如果是,则当前括号组合已经生成完毕,将 current
数组末尾设置为字符串结束符 \0
,然后输出当前括号组合。
否则,我们可以选择放置一个左括号。在 current
数组的当前位置 index
放置一个左括号,并递归调用 generateParentheses
函数,同时将左括号的数量加1。
然后,我们检查是否可以放置一个右括号。只有当已放置的右括号数量小于当前已放置的左括号数量时,我们才可以放置一个右括号。在 current
数组的当前位置 index
放置一个右括号,并递归调用 generateParentheses
函数,同时将右括号的数量加1。
在主函数中,我们首先读取输入的括号对数 N
。然后,我们定义一个字符数组 parentheses
来存储括号组合,初始时为空。接下来,我们调用 generateParentheses
函数,并传入初始的左括号数量、右括号数量、括号对数、parentheses
数组和初始的位置索引。
编译并运行上述代码可以解决该问题。你可以使用 C 语言编译器将代码保存为 .c
文件,然后编译并运行该文件来获取结果。
第5题:铺砖
对于一个2行N列的走道。现在用12,22的砖去铺满。问有多少种不同的方式。
时间限制:3000
内存限制:131072
输入
整个测试有多组数据,请做到文件底结束。每行给出一个数字N,0 <= n <= 250
输出
如题
样例输入
2
8
12
100
200
样例输出
3
171
2731
845100400152152934331135470251
1071292029505993517027974728227441735014801995855195223534251
要解决这个问题,我们可以使用动态规划来计算不同的铺砖方式。我们可以定义一个数组 dp
,其中 dp[i]
表示铺满一行长度为 2*i
的走道的不同铺砖方式数。
根据题目要求,我们可以有两种方式来铺满走道的一行:使用一块 1x2 的砖或者使用一块 2x2 的砖。
对于 dp[i]
,我们可以考虑最后铺砖的方式是使用一块 1x2 的砖,这样我们需要在 dp[i-1]
的基础上铺上这块砖。或者考虑最后铺砖的方式是使用一块 2x2 的砖,这样我们需要在 dp[i-2]
的基础上铺上这块砖。因此,我们可以得到递推关系:dp[i] = dp[i-1] + dp[i-2]
。
注意,初始情况下,当走道长度为0时,即 dp[0] = 1
,表示不需要铺砖的方式数为1。
下面是使用C语言编写的解题代码:
#include <stdio.h>unsigned long long int dp[251] = {0};void calculateDP() {dp[0] = 1;dp[1] = 1;dp[2] = 3;for (int i = 3; i <= 250; i++) {dp[i] = dp[i - 1] + dp[i - 2];}
}int main() {calculateDP();int N;while (scanf("%d", &N) == 1) {printf("%llu\n", dp[N]);}return 0;
}
在上述代码中,我们首先定义一个数组 dp
,用于存储不同的铺砖方式数。然后,我们定义了一个函数 calculateDP
来计算 dp
数组的值。在该函数中,我们通过遍历从 3 到 250 的走道长度,根据递推关系 dp[i] = dp[i-1] + dp[i-2]
计算不同的铺砖方式数。
在主函数中,我们首先调用 calculateDP
函数来计算 dp
数组。然后,我们使用一个循环来读取输入的走道长度 N
,并输出对应的不同铺砖方式数 dp[N]
。
编译并运行上述代码可以解决该问题。你可以使用 C 语言编译器将代码保存为 .c
文件,然后编译并运行该文件来获取结果。