PTA习题(C语言)
素数对猜想
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 freevoid init(int n, bool *is, int *pre, int *cnt) {for (int i = 2; i <= n; i++) {if (!is[i]) pre[(*cnt)++] = i;for (int j = 0; j < *cnt; j++) {int product = pre[j] * i;if (product > n) break;is[product] = true;if (i % pre[j] == 0) break;}}
}int main() {int n;scanf("%d", &n);// 动态分配数组bool *is = calloc(n + 1, sizeof(bool)); // 初始化为 false(分配内存并初始化)int *pre = malloc((n + 1) * sizeof(int));int cnt = 0;init(n, is, pre, &cnt);int ans = 0;for (int i = 1; i < cnt; i++) {if (pre[i] - pre[i-1] == 2) ans++;}printf("%d\n", ans);free(is);free(pre);return 0;
}
在C语言中,malloc
只需要一个参数,即要分配的总字节数。
calloc
不仅分配内存,还会将分配的内存初始化为零(对于数值类型,如 int
和 bool
,这意味着初始化为 false
)。
找出不是两个数组共有的元素
给定两个整型数组,本题要求找出不是两者共有的元素。
输入样例:
10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1
输出样例:
3 5 -15 6 4 1
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 freeint main() {int n, m;scanf("%d", &n);int *a = malloc(n*sizeof(int));for (int i = 0; i<n; i++){scanf("%d", &a[i]);}scanf("%d", &m);int *b = malloc(m*sizeof(int));for (int i = 0; i<m; i++){scanf("%d", &b[i]);}int *c = malloc((n+m)*sizeof(int));int k =0;for (int i = 0; i<n; i++){int flag = 0;for (int j = 0; j<m; j++){if (a[i] == b[j]) {flag = 1;break;}}if (flag == 0) c[k++] = a[i];}for (int i = 0; i<m; i++){int flag = 0;for (int j = 0; j<n; j++){if (b[i] == a[j]) {flag = 1;break;}}if (flag == 0) c[k++] = b[i]; }for (int i = 0; i<k; i++){for (int j = i+1; j<k; j++){if (c[i] == c[j]){for (int l = j+1; l<k; l++){c[l-1] = c[l];}k--;}}}for (int i = 0; i<k; i++){if (i == 0){printf("%d", c[i]);}else printf(" %d", c[i]);}return 0;
}
统计不同数字字符出现次数
从键盘读入一行字符(约定:字符数≤127字节),统计并显示该行字符中10个数字字符各自出现的次数,没有出现的字符不显示。如果没有数字字符,则输出"None!"。
输入样例
a053 JHSa 5we !=-)35xhyasei..df
输出样例
0-1
3-2
5-3
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
#include <string.h>int main() {int n, m;char a[128];gets(a);int num[10] = {0};for (int i = 0; i<strlen(a); i++){if (a[i] >= '0' && a[i] <= '9'){num[a[i]-'0']++;}}int flag = 0;for (int i = 0; i<10; i++){if (num[i] != 0){printf("%d-%d\n", i, num[i]);flag = 1;}}if (!flag){printf("None!");}return 0;
}
组个最小数
给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)。例如:给定两个0,两个1,三个5,一个8,我们得到的最小的数就是10015558。
现给定数字,请编写程序输出能够组成的最小的数。
输入样例:
2 2 0 0 0 3 0 0 1 0
输出样例:
10015558
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 freeint main() {int n, m;int num[10] = {0};for (int i = 0; i<10; i++){scanf("%d", &num[i]);}for (int i = 1; i<10; i++){if (num[i] != 0){printf("%d", i);num[i]--;break;}}for (int i = 0; i<10; i++){while (num[i]){printf("%d", i);num[i]--;}}return 0;
}
单词长度
你的程序要读入一行文本,其中以空格分隔为若干个单词,以.
结束。你要输出每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如it's
算一个单词,长度为4。注意,行中可能出现连续的空格;最后的.
不计算在内。
输入样例:
It's great to see you here.
输出样例:
4 5 2 3 3 4
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
#include <string.h>int main() {char ch;int num = 0, cnt = 0;int flag = 0;scanf("%c", &ch);while (ch != '.'){if (ch == ' '){if (num != 0){if (cnt == 0){printf("%d", num);}else printf(" %d", num);cnt++;}num = 0;}else num++;scanf("%c", &ch);}if (num != 0){if (cnt == 0){printf("%d", num);}else printf(" %d", num);}return 0;
}
IP地址转换
一个IP地址是用四个字节(每个字节8个位)的二进制码组成。请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出。
输入样例:
11001100100101000001010101110010
输出样例:
204.148.21.114
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
#include <string.h>int main() {char ch;for (int i = 0; i<4; i++){int s = 0;for (int j = 0; j<8; j++){scanf("%c", &ch);s = s*2+ch-'0';}printf("%d", s);if (i != 3){printf(".");}}return 0;
}
找鞍点
一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。
本题要求编写程序,求一个给定的n阶方阵的鞍点。
输入样例1:
4
1 7 4 1
4 8 3 6
1 6 1 2
0 7 8 9
输出样例1:
2 1
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
#include <string.h>
struct node{int x, y;
};
int max(int a, int b){if (a > b){return a;}else return b;
}
int min(int a, int b){return (a < b) ? a : b;
}
int main() {int n;scanf("%d", &n);int a[n][n];for (int i = 0; i<n; i++){for (int j=0; j<n; j++){scanf("%d", &a[i][j]);}}int h[n], l[n];for (int i = 0; i<n; i++){int max_h = 0, min_l = 10000;for (int j = 0; j<n; j++){max_h = max(max_h, a[i][j]);min_l = min(min_l, a[j][i]);}h[i] = max_h;l[i] = min_l;}struct node *p = (struct node*)malloc((n*n)*sizeof(struct node));int cnt = 0;for (int i = 0; i<n; i++){for (int j = 0; j<n; j++){if (a[i][j] == h[i] && a[i][j] == l[j]){p[cnt].x = i;p[cnt++].y = j;}}}if (cnt == 0){printf("NONE");} else{for (int i = 0; i<cnt; i++){printf("%d %d\n", p[i].x, p[i].y);}}return 0;
}
通讯录排序
输入n个朋友的信息,包括姓名、生日、电话号码,本题要求编写程序,按照年龄从大到小的顺序依次输出通讯录。题目保证所有人的生日均不相同。
输入样例:
3
zhang 19850403 13912345678
wang 19821020 +86-0571-88018448
qian 19840619 13609876543
输出样例:
wang 19821020 +86-0571-88018448
qian 19840619 13609876543
zhang 19850403 13912345678
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
#include <string.h>
struct student{char name[10];int birth;char phone[17];
}stu[10], stu1;
int main() {int n;scanf("%d", &n);for (int i = 0; i<n; i++){scanf("%s %d %s", stu[i].name, &stu[i].birth, stu[i].phone);}for (int i = 0; i<n-1; i++){for (int j = 0; j<n-1-i; j++){if (stu[j].birth > stu[j+1].birth){stu1 = stu[j];stu[j] = stu[j+1];stu[j+1] = stu1;}}}for (int i = 0; i<n; i++){printf("%s %d %s\n", stu[i].name, stu[i].birth, stu[i].phone);}return 0;
}
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
#include <string.h>
struct student{char name[10];int birth;char phone[17];
}stu[10], stu1;
int cmp(const void *a, const void *b){return (((struct student*)a)->birth - ((struct student*)b)->birth);
}
int main() {int n;scanf("%d", &n);for (int i = 0; i<n; i++){scanf("%s %d %s", stu[i].name, &stu[i].birth, stu[i].phone);}qsort(stu, n, sizeof(struct student), cmp);for (int i = 0; i<n; i++){printf("%s %d %s\n", stu[i].name, stu[i].birth, stu[i].phone);}return 0;
}
统计期末成绩
程序设计校选课期末计划安排在第十五周周五下午,有学生反映第十五周周末恰逢端午节假期,已请假提前回家。
经过协商,该课程期末考试共进行两次,分别在第十五周周五下午和第十六周周五下午。
如果学生两次考试都参加,则该课程期末成绩取两次成绩最高分。如果只参加了一次,则该次成绩即为期末考试成绩。
请你帮老师统计下每个学生该门课程的期末成绩。
输入样例:
3
201410300106 wanyun 70 88
201618050322 zhangyu 90 0
201509210118 lixiao 0 0
输出样例:
201410300106 wanyun 88
201509210118 lixiao 0
201618050322 zhangyu 90
AC代码:
#include <stdio.h>
#include <string.h>#define MAX_NAME_LENGTH 21
#define MAX_STUDENTS 10typedef struct {char id[16];char name[MAX_NAME_LENGTH];int score1;int score2;
} Student;int compareStudents(const void *a, const void *b) {return strcmp(((Student *)a)->id, ((Student *)b)->id);
}int main() {int n;scanf("%d", &n);Student students[MAX_STUDENTS];for (int i = 0; i < n; i++) {scanf("%s %s %d %d", students[i].id, students[i].name, &students[i].score1, &students[i].score2);}// 对学生按照学号进行排序qsort(students, n, sizeof(Student), compareStudents);for (int i = 0; i < n; i++) {int finalScore = (students[i].score1 > students[i].score2) ? students[i].score1 : students[i].score2;printf("%s %s %d\n", students[i].id, students[i].name, finalScore);}return 0;
}
qsort
函数:
qsort
是 C 标准库中的一个函数,用于对数组进行排序。它的原型定义在<stdlib.h>
头文件中。- 函数原型:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
-
void *base
: 这是指向要排序的数组的起始地址的指针。base
是一个void*
类型的指针,因此它可以指向任何类型的数组。 -
size_t nmemb
: 这是数组中元素的个数。nmemb
是一个size_t
类型的值,表示数组中要排序的元素数量。 -
size_t size
: 这是数组中每个元素的大小(以字节为单位)。size
是一个size_t
类型的值,表示数组中每个元素占用的内存大小。 -
int (*compar)(const void *, const void *)
: 这是一个指向比较函数的指针。比较函数用于确定数组中两个元素的顺序。compar
函数接收两个const void*
类型的指针,分别指向要比较的两个元素。
compareStudents
参数:
compareStudents
是一个函数指针,指向一个比较函数。- 比较函数的原型:
int compareStudents(const void *a, const void *b);
#include <stdio.h>
#include <string.h>#define MAX_NAME_LENGTH 21
#define MAX_STUDENTS 10typedef struct {char id[16];char name[MAX_NAME_LENGTH];int s1;int s2;
} Student;
int main() {int n;scanf("%d", &n);Student stu[MAX_STUDENTS], stu1;for (int i = 0; i < n; i++) {scanf("%s %s %d %d", stu[i].id, stu[i].name, &stu[i].s1, &stu[i].s2);}for (int i = 0; i<n-1; i++){for (int j = 0; j<n-i-1; j++){if (strcmp(stu[j].id, stu[j+1].id) > 0){stu1 = stu[j];stu[j] = stu[j+1];stu[j+1] = stu1;}}}for (int i = 0; i < n; i++) {int finalScore = (stu[i].s1 > stu[i].s2) ? stu[i].s1 : stu[i].s2;printf("%s %s %d\n", stu[i].id, stu[i].name, finalScore);}return 0;
}