数据结构和算法训练:第二十五弹

本文介绍了PAT(Assessment Test for Programmers)的四道模拟题,涉及模拟、最大公因数、分数运算、字符串操作等知识点。通过详细解析代码,展示了如何解决这些问题,包括学生录取、分数求和、中文数字读法及成绩排序等实际问题。
摘要由CSDN通过智能技术生成

1. 知识点总结

耗时:2h

得分:100/100

PAT知识点考察:模拟、最大公因数

本次基本上都是模拟居多,考察数据结构和算法的比例相对较小,不是很难,主要是考察耐心和英文理解的能力

题目难度知识点
1080 Graduate Admission🎯模拟
1081 Rational Sum🎯最大公因数、分数运算
1082 Read Number in Chinese🎯🎯模拟、字符串操作
1083 List Grades🎯模拟

2. 分题题解

2.1 1080 Graduate Admission

模拟题,不是很难,读懂题目意思即可~

需要将学生排序,排序后按照题目要求划分rank,从rank高的开始依次进行录取

注意输出的时候需要对学生编号排序

#include<bits/stdc++.h>
using namespace std;
int N,M,K;
vector<int>need;//各个学校需要的人数
struct Student{
	int Ge,Gi,Gf;
	int rank;
	int id;
	vector<int>ask;
}; 
vector<vector<int> >ans;//录取结果 
vector<int>last_in;
vector<Student>stu;
bool cmp(Student a,Student b){
	if(a.Gf!=b.Gf){
		return a.Gf>b.Gf;
	}else{
		return a.Ge>b.Ge;
	}
}
int main(){
	scanf("%d%d%d",&N,&M,&K);
	need.resize(M);
	ans.resize(M);
	stu.resize(N);
	last_in.resize(M,0);//某学校最后录取的学生排名 
	for(int i=0;i<M;i++){
		scanf("%d",&need[i]);
	}
	for(int i=0;i<N;i++){
		scanf("%d%d",&stu[i].Ge,&stu[i].Gi);
		stu[i].id=i;
		stu[i].Gf=(stu[i].Ge+stu[i].Gi+5)*10/20;
		stu[i].ask.resize(K);
		for(int j=0;j<K;j++){
			scanf("%d",&stu[i].ask[j]);
		}
	}
	//首先给各个学生排序 
	sort(stu.begin(),stu.end(),cmp);
	int cnt=1;
	for(int i=0;i<N;i++){
		if(i==0){
			stu[i].rank=cnt;
		}else{
			if(stu[i].Gf==stu[i-1].Gf&&stu[i].Ge==stu[i-1].Ge){
				stu[i].rank=cnt;
			}else{
				cnt++;
				stu[i].rank=cnt;
			}
		}
		//下面分配
		for(int j=0;j<stu[i].ask.size();j++){
			int sid=stu[i].ask[j];
			int id=stu[i].id;
			//成功录取 
			if(need[sid]>0){
				need[sid]--;
				ans[sid].push_back(id);
				last_in[sid]=stu[i].rank;
//				printf("学校:%d 学生:%d\n",sid,id);
				break;
			}else if(last_in[sid]==stu[i].rank){
				need[sid]--;
				ans[sid].push_back(id);
//				printf("学校:%d 学生:%d\n",sid,id);
				break;
			}
		} 
	}
	for(int i=0;i<M;i++){
		sort(ans[i].begin(),ans[i].end());
		for(int j=0;j<ans[i].size();j++){
			if(j){
				printf(" ");
			}
			printf("%d",ans[i][j]);
		}
		printf("\n");
	}
	return 0;
} 

2.2 1081 Rational Sum

参考前一次的模拟练习,定义分数的加法运算部分和分数输出结果部分的函数,调用即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
	if(a<b)swap(a,b);
	ll temp;
	while(b){
		temp=b;
		b=a%b;
		a=temp;
	}
	return a;
}
struct Node{
	ll numerator,denominator;
};
vector<Node>nodes;
int N;
Node ans;
Node Add(Node a,Node b){
	// a/b + c/d = (a*d+c*b)/b*d
	Node c;
	c.numerator=a.numerator*b.denominator+a.denominator*b.numerator;
	c.denominator=a.denominator*b.denominator;
	ll temp=gcd(abs(c.numerator),abs(c.denominator));
	c.numerator/=temp;
	c.denominator/=temp;
	return c;
}
void Print(Node a){
	if(a.numerator==0){
		printf("0");
		return;
	}
	bool neg=a.numerator<0?true:false;
	ll num=a.numerator/a.denominator;
	a.numerator-=num*a.denominator;
	
	if(neg){
		printf("-");
	}
	if(num){
		printf("%lld",abs(num));
	}
	if(a.numerator){
		if(num)printf(" ");
		printf("%lld/%lld",abs(a.numerator),abs(a.denominator));
	}
	
}
int main(){
	scanf("%d",&N);
	nodes.resize(N);
	for(int i=0;i<N;i++){
		scanf("%lld/%lld",&nodes[i].numerator,&nodes[i].denominator);
	}
	ans=nodes[0];
	for(int i=1;i<N;i++){
		ans=Add(ans,nodes[i]);
	}
	Print(ans);
	return 0;
}

2.3 1082 Read Number in Chinese

模拟,个人感觉是比较繁琐的一道题目,对于输出而言,首先需要判断某位置的数字是否为零,若为零需要分类讨论(比如在某单位连续的四个数字中是否均为0等等)我觉得我代码中考虑的不全面,但是AC了,所以有遗漏不足的地方欢迎批评指正

#include<bits/stdc++.h>
using namespace std;
string str,ans="";
int num;
int len;
string table[]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu","shi"};
int main(){
	cin>>str;
	if(str[0]=='-'){
		printf("Fu ");
		str=str.substr(1,str.length());
	}
	len=str.length();
	// 1 0000 0000 
	bool hasValue=false;
	for(int i=0;i<len;i++){
		int pos=(len-i-1)%4;
		if(str[i]!='0'){
			hasValue=true;
			ans+=" ";
			ans+=table[str[i]-'0'];
			if(pos==1){
				ans+=" Shi";
			}else if(pos==2){
				ans+=" Bai";
			}else if(pos==3){
				ans+=" Qian";
			}
		}else if(str[i]=='0'){
			if(pos==3&&(str[i+1]!='0'||str[i+2]!='0'||str[i+3]!='0')){
				ans+=" ling";
			}else if(pos==2&&str[i-1]!='0'&&(str[i+1]!='0'||str[i+2]!='0')){
				ans+=" ling";
			}else if(pos==1&&str[i-1]!='0'&&str[i+1]!='0'){
				ans+=" ling";
			}
		}
		//单位的添加 
		if(pos==0&&hasValue){
			if((len-i-1)/4==1){
				ans+=" Wan";
			}else if((len-i-1)/4==2){
				ans+=" Yi";
			}
			hasValue=false;
		}
	}
	bool flag=false;
	for(int i=0;i<ans.length();i++){
		if(ans[i]==' '&&!flag){
			continue;
		}else{
			printf("%c",ans[i]);
			flag=true;
		}
	}
	if(!flag){
		printf("ling");
	}
	return 0;
} 

2.4 1083 List Grades

模拟,只用了sort和stl所以总体没啥难度

#include<bits/stdc++.h>
using namespace std;
int N;
struct Student{
	string name;
	string id;
	int grade;
};
int grade1,grade2;
vector<Student>stu;
bool cmp(Student a,Student b){
	return a.grade>b.grade;
}
int cnt=0;
int main(){
	scanf("%d",&N);
	stu.resize(N);
	for(int i=0;i<N;i++){
		cin>>stu[i].name>>stu[i].id>>stu[i].grade;
	}
	scanf("%d%d",&grade1,&grade2);
	sort(stu.begin(),stu.end(),cmp);
	for(int i=0;i<N;i++){
		if(stu[i].grade>grade2){
			continue;
		}else if(stu[i].grade<grade1){
			break;
		}else{
			cnt++;
			printf("%s %s\n",stu[i].name.c_str(),stu[i].id.c_str());
		}
	}
	if(cnt==0){
		printf("NONE");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值