PAT A1039 Course List for Student (25)-PAT甲级真题

题目在这:题目传送门

题目大概的意思呢,就是有N个学生,K门课,给出选择每门课的学生姓名,并在最后给出N个学生的姓名,要求按顺序给出每个学生的选课情况。依次输出学生的姓名,选课数,课程的代号。

我自己写代码的时候准备拿每个课程对应建立vector,但是在vector存放string的时候卡住了,后来搜到了柳神的代码,仔细拜读了一下,在这篇博客里详细讲解。思路有所不同。

这个题目的核心就是用vector存数据。
思路概览:

  1. 把学生的名字XXXX(前三个是英文,第四个是数字)转换成一个int,手写一个hash的方法,映射出来每个名字对应的值。
  2. 每个学生选的课,存在对应(名字映射出来的hash值)下标的vector里面。
  3. 最后用sort函数排序之后输出。

有了这个思路呢,就好写代码了。

首先根据第一点:

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int getid(char *name){
	int id = 0;
	for(int i = 0;i<3;i++)//因为前三个是英语,所以for只要做三次
		id = 26 * id + name[i] - 'A';//这个就是把每个英语字母取出来(类似于转换为26进制存起来)
	id = id * 10 + name[3] - '0';//这个是把id后面加个0,用后面的数字填上去。
	return id;
}
const int maxn = 26 * 26 * 26 * 10 + 10;
vector<int> v[maxn]; 

这一部分写出了思路的第一个,封装成了getid。

int main(){
	int n,m,no,num,id=0;
	char name[5];
	scanf("%d %d",&n,&m);
	for(int i=0;i<m;i++){
		scanf("%d %d",&no,&num);
		for(int j=0;j<num;j++){
			scanf("%s",name);//存名字
			id = getid(name);//转换成int
			v[id].push_back(no);//课程序号存入对应的int下标中的vector的后面
		}
	}

这一部分写出了思路的第二个,存起来了每个学生对应的课程号。

//接上面的代码
	for(int i = 0;i<n;i++){
	scanf("%s",name);//读取学生名字
	id = getid(name);//转换成int
	sort(v[id].begin(),v[id].end());//找到这个int对应的vector排序
	printf("%s %d",name,v[id].size());//打印这个名字,和这个学生选课数目
	for(int i = 0; i<v[id].size();i++)
		printf(" %d",v[id][i]);//打印每一个课的序号
	printf("\n");
	}
}

这一部分代码处理输入数据的最后一行,读取,排序,输出。
完整代码:


#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int getid(char *name){
	int id = 0;
	for(int i = 0;i<3;i++)
		id = 26 * id + name[i] - 'A';
	id = id * 10 + name[3] - '0';
	return id;
}
const int maxn = 26 * 26 * 26 * 10 + 10;
vector<int> v[maxn]; 
int main(){
	int n,m,no,num,id=0;
	char name[5];
	scanf("%d %d",&n,&m);
	for(int i=0;i<m;i++){
		scanf("%d %d",&no,&num);
		for(int j=0;j<num;j++){
			scanf("%s",name);
			id = getid(name);
			v[id].push_back(no);
		}
	}
	for(int i = 0;i<n;i++){
	scanf("%s",name);
	id = getid(name);
	sort(v[id].begin(),v[id].end());
	printf("%s %d",name,v[id].size());
	for(int i = 0; i<v[id].size();i++)
		printf(" %d",v[id][i]);
	printf("\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值