PTA习题(C语言)
素数对猜想
AC代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> // 用于 malloc 和 free
void 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 和 free
int 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 和 free
int 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;
}