一、哥德巴赫猜想
题目描述
输入一个偶数 N,验证 4~N 所有偶数是否符合哥德巴赫猜想:任一大于 2 的偶数都可写成两个质数之和。如果一个数不止一种分法,则输出第一个加数相比其他分法最小的方案。例如 10,10=3+7=5+5则 10=5+5是错误答案。
输入格式
第一行输入一个正偶数 N
输出格式
输出 (N-2)/2 行。对于第 i 行:
首先先输出正偶数 2i+2,然后输出等号,再输出加和为 2i+2 且第一个加数最小的两个质数,以加号隔开。
输入输出样例
输入 #1
10
输出 #1
4=2+2 6=3+3 8=3+5 10=3+7
我的代码:
#include<stdio.h>
#include<math.h>
//定义一个函数判断是否为素数
int is_sushu(n){
int i;
if(n<=1){
return 0;
}
for(i=2;i<=sqrt(n);i++){
if(n%i==0){
return 0;
}
}
return 1;
}
void ge(N){
int i,j;
for(i=4;i<=N;i++){
if(i%2==0){//当i为偶数时进行内循环
for(j=2;j<=i/2;j++){
if(is_sushu(j)&&is_sushu(i-j)){//判断两个加数是否均为素数
printf("%d=%d+%d\n",i,j,i-j);
break;
}
}
}
}
}
int main(){
int N;
scanf("%d",&N);
ge(N);
return 0;
}
原代码的错误点在于第一个素数判断函数出现错误,没有考虑n<2的情况,且将n%i==0错写为i%n。
经以上修改后的代码运行后输入样例10,输出结果为:
(剩下的几个题都是我考核的时候不会所以没写的>_<)
二、方块转换
题目描述
一块 n \times nn×n 正方形的黑白瓦片的图案要被转换成新的正方形图案。写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式:
-
转 90\degree90°:图案按顺时针转 90\degree90°。
-
转 180\degree180°:图案按顺时针转 180\degree180°。
-
转 270\degree270°:图案按顺时针转 270\degree270°。
-
反射:图案在水平方向翻转(以中央铅垂线为中心形成原图案的镜像)。
-
组合:图案在水平方向翻转,然后再按照 1∼3 之间的一种再次转换。
-
不改变:原图案不改变。
-
无效转换:无法用以上方法得到新图案。
如果有多种可用的转换方法,请选择序号最小的那个。
只使用上述 7 个中的一个步骤来完成这次转换。
输入格式
第一行一个正整数 n。
然后 n行,每行 n 个字符,全部为 @
或 -
,表示初始的正方形。
接下来 n 行,每行 n 个字符,全部为 @
或 -
,表示最终的正方形。
输出格式
单独的一行包括 1∼7 之间的一个数字(在上文已描述)表明需要将转换前的正方形变为转换后的正方形的转换方法。
输入输出样例
输入 #1
3 @-@ --- @@- @-@ @-- --@
输出 #1
1
通过查阅资料,基本思路如下:
- 需要定义几个辅助函数来进行矩阵操作和判断:
is_matrix_equal
:用于判断两个矩阵是否相等。rotate_90
:将矩阵顺时针旋转90度;reflect
:将矩阵水平翻转。 - 定义一个
transform_pattern
函数来进行图案的转换。该函数接受初始矩阵initial
、目标矩阵target
和矩阵的大小n
作为参数。函数中的转 换方法按照题目描述的顺序进行尝试,并通过调用辅助函数来进行判断。 -
在
main
函数中,输入的矩阵大小n
。然后使用循环逐行读取初始矩阵和目标矩阵的元素,并存储在对应的数组中。 -
调用
transform_pattern
函数将初始矩阵转换为目标矩阵,并将返回的转换方式打印输出。
代码如下:
#include <stdio.h>
#include <stdbool.h>
//判断两个矩阵是否相等
bool is_matrix_equal(char matrix1[][10], char matrix2[][10], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix1[i][j] != matrix2[i][j]) {
return false;
}
}
}
return true;
}
//将矩阵顺时针旋转90度
void rotate_90(char matrix[][10], int n) {
char temp[10][10];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
temp[j][n - 1 - i] = matrix[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = temp[i][j];
}
}
}
//水平翻转矩阵
void reflect(char matrix[][10], int n) {
char temp[10][10];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
temp[i][j] = matrix[i][n - 1 - j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = temp[i][j];
}
}
}
//转换图案并返回转换方式
int transform_pattern(char initial[][10], char target[][10], int n) {
//直接转换90度
rotate_90(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 1;
}
//直接转换180度
rotate_90(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 2;
}
//直接转换270度
rotate_90(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 3;
}
//反射
reflect(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 4;
}
//组合转换
reflect(initial, n);
rotate_90(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 5;
}
rotate_90(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 6;
}
rotate_90(initial, n);
if (is_matrix_equal(initial, target, n)) {
return 7;
}
//无效转换
return -1;
}
int main() {
int n;
char initial[10][10];
char target[10][10];
scanf("%d", &n);
//读取初始矩阵
for (int i = 0; i < n; i++) {
scanf("%s", initial[i]);
}
//读取目标矩阵
for (int i = 0; i < n; i++) {
scanf("%s", target[i]);
}
//转换图案并输出转换方式
int transformation = transform_pattern(initial, target, n);
printf("%d\n", transformation);
return 0;
}
例:
三、神奇的幻方
题目描述
幻方是一种很神奇的 N×N 矩阵:它由数字 N1,2,3,⋯⋯,N×N 构成,且每行、每列及两条对角线上的数字之和都相同。
当 N 为奇数时,我们可以通过下方法构建一个幻方:
首先将 1写在第一行的中间。
之后,按如下方式从小到大依次填写每个数 K (K=2,3,⋯,N×N) :
- 若 (K-1)在第一行但不在最后一列,则将 K 填在最后一行,(K−1) 所在列的右一列;
- 若 (K-1)在最后一列但不在第一行,则将 K 填在第一列,(K−1) 所在行的上一行;
- 若 (K-1)在第一行最后一列,则将 K 填在(K−1) 的正下方;
- 若 (K-1)既不在第一行,也不在最后一列,如果(K−1) 的右上方还未填数,则将 KK 填在 (K-1) 的右上方,否则将 K填在(K−1) 的正下方。
现给定 N,请按上述方法构造 N×N 的幻方。
输入格式
一个正整数 N,即幻方的大小。
输出格式
共 N 行,每行 N 个整数,即按上述方法构造出的 N×N 的幻方,相邻两个整数之间用单空格隔开。
输入输出样例
输入 #1
3
输出 #1
8 1 6 3 5 7 4 9 2
代码如下:
#include <stdio.h>
void construct_magic_square(int square[][15], int n) {
int i, j;
int num = 1;
int row = 0, col = n / 2;
while (num <= n * n) {
square[row][col] = num;
i = (row - 1 + n) % n;
j = (col + 1) % n;
if (square[i][j] != 0) {
row = (row + 1) % n;
} else {
row = i;
col = j;
}
num++;
}
}
int main() {
int n;
int magic_square[15][15] = {0}; // 初始化幻方矩阵
scanf("%d", &n);
construct_magic_square(magic_square, n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", magic_square[i][j]);
}
printf("\n");
}
return 0;
}
例:
四、笨小猴
题目描述
笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!
这种方法的具体描述如下:假设maxn 是单词中出现次数最多的字母的出现次数,minn 是单词中出现次数最少的字母的出现次数,如果maxn−minn 是一个质数,那么笨小猴就认为这是个 Lucky Word,这样的单词很可能就是正确的答案。
输入格式
一个单词,其中只可能出现小写字母,并且长度小于100。
输出格式
共两行,第一行是一个字符串,假设输入的的单词是 Lucky Word,那么输出 Lucky Word
,否则输出 No Answer
;
第二行是一个整数,如果输入单词是 Lucky Word
,输出maxn−minn 的值,否则输出0。
输入输出样例
输入 #1
error
输出 #1
Lucky Word 2
输入 #2
olympic
输出 #2
No Answer 0
代码如下:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
//判断是否为质数
bool is_prime(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() {
char word[105];
int count[26]={0}; //统计每个字母出现的次数
int max_count=0, min_count=100;
int diff;
//读取输入的单词
scanf("%s", word);//数组名即为数组元素首地址
int len=strlen(word);
// 统计每个字母出现的次数
for (int i = 0; i < len; i++) {
count[word[i] - 'a']++;
}
// 找到出现次数最多和最少的字母出现次数
for (int i = 0; i < 26; i++) {
if (count[i] > max_count) {
max_count = count[i];
}
if (count[i] < min_count && count[i] > 0) {
min_count = count[i];
}
}
// 计算差值
diff = max_count - min_count;
// 判断差值是否为质数
if (is_prime(diff)) {
printf("Lucky Word\n");
printf("%d\n", diff);
} else {
printf("No Answer\n");
printf("0\n");
}
return 0;
}
例:
五、查找
题目描述
输入 n 个不超过 10^9 的单调不减的(就是后面的数字不小于前面的数字)非负整数a1,a2,…,an,然后进行 m 次询问。对于每次询问,给出一个整数 q,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 −1 。
输入格式
第一行 2 个整数 n 和 m,表示数字个数和询问次数。
第二行 n 个整数,表示这些待查询的数字。
第三行 m 个整数,表示询问这些数字的编号,从 1 开始编号。
输出格式
输出一行,m 个整数,以空格隔开,表示答案。
输入输出样例
输入 #1
11 3 1 3 3 3 5 7 9 11 13 15 15 1 3 6
输出 #1
1 2 -1
代码如下:
#include <stdio.h>
int main() {
int n, m;
int num[1005];
//输入数字个数和询问次数
scanf("%d %d", &n, &m);
//输入待查询的数字
for (int i = 0; i < n; i++) {
scanf("%d", &num[i]);
}
//查询
for (int i = 0; i < m; i++) {
int q, ans = -1;
scanf("%d", &q);
//找到第一次出现的编号
for (int j = 0; j < n; j++) {
if (num[j] == q) {
ans = j + 1;
break;
}
}
printf("%d ", ans);
}
printf("\n");
return 0;
}
例: