PAT乙级 ------ 1041~1045 附代码及思路 考试座位号、字符统计、输出PATest、火星数字、快速排序

本文探讨了五个编程实例,涉及排序、字符统计、字符串转换和快速查找等,同时融入莫泊桑的人生观,展示了信息技术在实际问题中的应用与生活智慧的结合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    也许他们会明白莫泊桑的一句话:生活可能不像你想象得那么好,但也不会像你想象得那么糟。人的脆弱和坚强都超乎自己的想象。有时,可能脆弱得一句话就泪流满面;有时,也发现自己咬着牙走了很长的路。


1041 考试座位号
思路: 定义一个结构体含:准考证号,试机位,考试位;定义结构体数组,循环存储考生信息,最后根据试机位输出考生准考证号和考试位。

#include<stdio.h>
#define LEN 1000

typedef struct _info {
	char id[17];
	int _loc;//试机位
	int loc;//考试机位
} Info;

int main() {
	Info info[LEN];
	int cnt, tmp;
	scanf("%d", &cnt);
	for(int i=0; i<cnt; i++)
		scanf("%s %d %d", &info[i].id, &info[i]._loc, &info[i].loc);
	scanf("%d", &cnt);
	while(cnt-- > 0) {
		int index = 0;
		scanf("%d", &tmp);
		while(info[index++]._loc != tmp) {}
		printf("%s %d\n",info[index-1].id, info[index-1].loc);
	}
	return 0;
}

在这里插入图片描述
1042 字符统计
思路: 字符的asc码作数组下标,通过getchar()逐个处理字符,输入过程中确定最大值,及最大值下标。注意:出现频次相同时输出字母序较小的。

#include<stdio.h>
#include<ctype.h>
#define LEN 130

int main() {
	int ch, maxIndex, asc[LEN] = {0};
	while((ch=getchar()) != '\n') {
		if(!isalpha(ch))//非字母不处理
			continue;
		ch = tolower(ch);//输出要求小写,则全部转为小写
		asc[ch]++;
		if((asc[ch]==asc[0] && ch<maxIndex)|| asc[ch]>asc[0] ) {//注意出现次数相同时要字母序小的
			asc[0] =asc[ch];
			maxIndex = ch;
		}
	}
	printf("%c %d",maxIndex, asc[maxIndex]);
	return 0;
}

在这里插入图片描述
1043 输出PATest
思路: 就是一个统计给定字符串中 “PATest”各字符的数量,之后按“PATest”顺序输出。

#include<stdio.h>

int main() {
	char str[] = "PATest";
	int ch, cnt, arr[6] = {0};
	while((ch=getchar()) != '\n') {
		switch(ch) {
			case 'P':
				arr[0]++;
				break;
			case 'A':
				arr[1]++;
				break;
			case 'T':
				arr[2]++;
				break;
			case 'e':
				arr[3]++;
				break;
			case 's':
				arr[4]++;
				break;
			case 't':
				arr[5]++;
				break;
		}
	}
	cnt = 0;
	for(int i=0; i<6; i++)
		cnt += arr[i];
	while(cnt) {
		for(int i=0; i<6; i++) {
			if(arr[i]) {
				putchar(str[i]);
				arr[i]--;
				cnt--;
			}
		}
	}
	return 0;
}

在这里插入图片描述
1044 火星数字
思路: 数字转火星文即10进制转13进制,不赘述。火星文转数字:题目给定取值范围即火星文最多为两位数字,所以两位的火星文中间会存在空格,不能用scanf,使用fgets()获取一整行,通过strtok()分割字符,strcmp()进行字符串比较。

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define LEN 11
//个位数组
char *units[]= {"tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec"};
//十位数组
char *tens[]= {"tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"};

int Change(char* s) {
	if(s) {
		for(int i=0; i<12; i++) {
			if(strcmp(s,tens[i]) == 0)
				return (i+1)*13;
		}
		for(int i=0; i<13; i++) {
			if(strcmp(s,units[i]) == 0)
				return i;
		}
	}
	return 0;
}

int main() {
	int cnt, num;
	char str[LEN];
	scanf("%d\n", &cnt);
	while(cnt-- > 0) {
		fgets(str, LEN, stdin);
		if(isdigit(str[0])) {
			sscanf(str, "%d", &num);
			if(num/13 && num%13)
				printf("%s %s\n", tens[num/13-1], units[num%13]);
			else if(num/13 && num%13 == 0)
				printf("%s\n", tens[num/13-1]);
			else if(num/13 == 0)
				printf("%s\n", units[num]);
		} else {
			num = Change(strtok(str," \n"));
			num += Change(strtok(NULL, " \n"));
			printf("%d\n", num);
		}
	}
	return 0;
}

在这里插入图片描述
1045 快速排序
思路: 对于序列中的一个数,如果它大于其左边所有元素中的最大值,并且小于其右边所有元素的最小值,那它就是主元。基于这个思路:在录入数组元素的循环中确定每个元素左边的最大值,之后再从尾到头遍历数组确定每个元素右边的最小值。最后输出符合条件的元素。测试点2: 合法元素个数为0时,需额外输出一行空行,即0下边有两个空行。(见末尾截图)

#include<stdio.h>
#define LEN 100010

typedef struct _arr {
	int value;//元素值
	int lMax;//该元素左边所有元素的最大值
	int flag;
} Arr;

int main() {
	int n, rMin;
	Arr arr[LEN];
	scanf("%d", &n);
	arr[0].value = arr[0].lMax = 0;
	for(int i=1; i<=n; i++) {
		scanf("%d", &arr[i].value);
		arr[i].lMax = arr[i-1].value > arr[i-1].lMax ? arr[i-1].value : arr[i-1].lMax;
		if(arr[i].value > arr[i].lMax)//该元素大于其左边所有元素
			arr[i].flag = 1;
		else
			arr[i].flag = 0;
	}
	rMin = 1000000005;
	for(int i=n; i>0; i--) {
		if(arr[i].flag) {
			if(arr[i].value < rMin)
				arr[0].value++;
			else
				arr[i].flag = 0;
		}
		rMin = arr[i].value < rMin ? arr[i].value : rMin;//确定右半表最小元素
	}
	printf("%d\n", arr[0].value);
	if(!arr[0].value)
		putchar('\n');
	for(int i=1; arr[0].value>0; i++) {
		if(arr[i].flag) {
			printf("%d",arr[i].value);
			arr[0].value--;
			if(arr[0].value > 0)
				putchar(' ');
		}
	}
	return 0;
}

在这里插入图片描述
主元个数为0时:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值