题目https://pintia.cn/problem-sets/994805342720868352/problems/994805447855292416
问题:https://paste.ubuntu.com/p/8ZbTPbqpMY/
三种方法:
法一:正确。
法二:在法一基础上把hash数组映射至vector数组,减小vector规模。输出少了最后两行,不知哪里的问题.
改正:确实是vector数组变量与常量的问题。变量k+1就少两行。改成常量40004就正确。但仍旧有一个测试点没过:段错误/运行超时。
3.11改正:常量改成262626+2才正确。因为查询的学生人数是40000.但总共的学生可能远超这么多。所以只能从命名方式来推测学生总人数。
法三:vector+string。一个测试点超时。主要是这个代码里用的变量显示正确,所以才没怀疑变量常量的问题。超时问题仍未解决。因为学生时262626+2这么多,所以两层循环不可以。但是,写成双循环已可得23分。不必求满分。
法一:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int hashfunc(char str[]){
int sum=0;
for(int i=0;i<3;i++){
sum=sum*26+(str[i]-'A');
}
sum=sum*10+(str[3]-'0');//*26则段错误。*10才正确。
return sum;
}
vector<int> stuscour[175761];//26*26*26+10
int main(){
int n,k,cid,stuid,nstu;
scanf("%d%d",&n,&k);
char tempstr[6];
for(int j=0;j<k;j++){
scanf("%d%d",&cid,&nstu);
while(nstu--){
scanf("%s",tempstr);
stuid=hashfunc(tempstr);
stuscour[stuid].push_back(cid); //把课程编号加入学生的数组中
}
}
while(n--){
scanf("%s",tempstr);
stuid=hashfunc(tempstr);//查询
sort(stuscour[stuid].begin(),stuscour[stuid].end());//排序
printf("%s %d",tempstr,stuscour[stuid].size());
vector<int>::iterator it=stuscour[stuid].begin();
for(;it!=stuscour[stuid].end();it++){//输出
printf(" %d",*it);
}
printf("\n");
}
return 0;
}
法二:
//输入有问题:我不应该省事全输入小写 (已解决)
//问题二:没排序(已解决)
//问题三:本地IDE输出少两行,PAT编译错误
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int hashfunc(char str[]){
int sum=0;
for(int i=0;i<3;i++){
sum=sum*26+(str[i]-'A');
}
sum=sum*10+(str[3]-'0');
return sum;
}
int main(){
int n,k,cid,id,nstu,num=1;
scanf("%d%d",&n,&k);
char tempstr[6];
int hash[175761]={false};//使course数组规模减小,与法3对比
vector<int> course[k+1];
for(int j=0;j<k;j++){
scanf("%d%d",&cid,&nstu);
while(nstu--){
scanf("%s",tempstr);
id=hashfunc(tempstr);
if(!hash[id]){
hash[id]=num; //学生id映射到num
course[num++].push_back(cid);
}else{
course[hash[id]].push_back(cid);
}
}
}
while(n--){
scanf("%s",tempstr);
id=hashfunc(tempstr);
sort(course[hash[id]].begin(),course[hash[id]].end());
printf("%s %d",tempstr,course[hash[id]].size());
for(vector<int>::iterator it=course[hash[id]].begin();it!=course[hash[id]].end();it++){
printf(" %d",*it);
}
printf("\n");
}
return 0;
}
法三:
课程从1-m,所以数组范围要正确。问题2:一个测试点超时。用scanf也超时。所以问题应该是最后的两层循环?Ps不用vector也可以。因为学生参加的课程数量上限是m.
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<iostream>
using namespace std;
int main(){
int n,m,cid,nstu;
scanf("%d%d",&n,&m);
vector<string> course[m+1];
string temp;
for(int j=0;j<m;j++){//输入每门课程人数信息
scanf("%d%d",&cid,&nstu);//课程编号,课程人数
while(nstu--){//输入每门课程的学生
cin>>temp;
course[cid].push_back(temp);
}
}
while(n--){//查询课程的人数
cin>>temp;//当前查询的学生
int cnt=0;//所报课程个数为0
vector<int> ans;//课程编号
for(int i=1;i<=m;i++){//按课程编号顺序查询
for(vector<string>::iterator it=course[i].begin();it!=course[i].end();it++){//在每门课程的报名学生中一个个比对名字
if(temp==*it){//比对成功
cnt++;
ans.push_back(i);
break;
}
}
}
printf("%s %d",temp.c_str(),cnt);//输出学生名,总课程数
for(vector<int>::iterator it=ans.begin();it!=ans.end();it++){
printf(" %d",*it);//挨个输出课程编号
}
printf("\n");
}
return 0;
}