人之为学,不日进则日退。
最初的想法是用结构体把每本书的所有信息都存下来,查询的时候遍历结构体,但交上去只过了一个测试点(目前还没想出来哪有问题)。后来想着用map映射,但此题并非简单的key-value一一对应,而是一对多的关系,一个关键字可能对应多个值(同一个作者对应很多本书,同一家出版社出版很多本书),然后就卡住了。平时学习还是不够深入,只会最简单的map,稍微复杂一点的就没怎么写过了-_-
“新技能get”:用map+set实现一对多(因为本题要涉及到排序,所以用set自动去重并排序),用map+vector也可实现
参考了其他大神的代码,也学到了灵活使用格式化输入输出的妙处!
同时,对于他们提到的“传参一定要用引用,否则最后一组数据可能会超时 ”
函数参数按值传递,在传递大数据时(如本题传递map),在时间上的开销较大,所以可能超时。故改用引用传递。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
map<string,set<int> >mptitle,mpauthor,mpkey,mppublish,mpyear;
void check(map<string,set<int> >&mp,string &s){
if(mp.find(s)==mp.end()){//在整个map容器内查找
cout<<"Not Found\n";
}
else{
set<int>::iterator it;
for(it=mp[s].begin();it!=mp[s].end();it++){
printf("%07d\n",*it);//一定要注意输出七位!
}
}
}
int main() {
int n;
scanf("%d",&n);
while(n--){
int id;
string title,author,key,publish,year;
scanf("%d",&id);
char c=getchar();//吸收换行和空格
getline(cin,title);
mptitle[title].insert(id);
getline(cin,author);
mpauthor[author].insert(id);
while(cin>>key){//一个一个的输入,不要一股脑的getline
mpkey[key].insert(id);
c=getchar();
if(c=='\n') break;
}
getline(cin,publish);
mppublish[publish].insert(id);
getline(cin,year);
mpyear[year].insert(id);
}
int m;
scanf("%d",&m);
while(m--){
int k;
string s;
scanf("%d: ",&k);//善用scanf
getline(cin,s);
cout<<k<<": "<<s<<endl;
if(k==1) check(mptitle,s);
else if(k==2) check(mpauthor,s);
else if(k==3) check(mpkey,s);
else if(k==4) check(mppublish,s);
else if(k==5) check(mpyear,s);
}
return 0;
}