第六章 C++标准模板库介绍
6.1 vector
6.2 set
【例】A1063 Set Similarity (25 分)
ATTENTION
- 将两个set合并成一个set最后一个测试点会超时…
- 只有一个点超时的时候,还是可以挣扎一下的!
#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
int n,m,k;
set<int> st[60];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>m;
for(int j=1;j<=m;j++)
{
int tmp;
cin>>tmp;
st[i].insert(tmp);
}
}
cin>>k;
for(int i=0;i<k;i++)
{
int a,b;
cin>>a>>b;
int sum=st[a].size();
for(set<int>::iterator it=st[b].begin();it!=st[b].end();it++)
{
if(st[a].find(*it)==st[a].end())
sum++;
}
double ans=(st[a].size()+st[b].size())-sum*1.0;
printf("%.1f%\n",ans/sum*100);
}
return 0;
}
【例】A1144 The Missing Number (20 分)
水题
#include <cstdio>
#include <set>
using namespace std;
int n,ans=1;
set<int> st;
int main()
{
scanf("%d",&n);
int max=0;
for(int i=0;i<n;i++)
{
int tmp;
scanf("%d",&tmp);
if(tmp>0)
st.insert(tmp);
}
for(set<int>::iterator it=st.begin();it!=st.end();it++)
{
if(ans!=*it)
{
printf("%d",ans);
return 0;
}
else
ans++;
}
printf("%d",ans);
return 0;
}
【例】1129 Recommendation System (25 分)
ATTENTION
- 用sort排序会超时。数据规模1e4,sort复杂度为O(nlogn),在极限状况下为n2logn,超时无疑。(但没时间的情况下,拿到大部分分数还是必要的)
- 在sort会超时的情况下,选择
set
,重载<
,实现排序。
struct per{
int data,cnt;
bool operator < (const per &a) const
{
if(cnt==a.cnt) return data<a.data;
else return cnt>a.cnt;
}
};
set<per> st;
- 每次更新频率前,先在set中寻找这个data,如果有,要先删除,再插入新的。
#include <cstdio>
#include <set>
using namespace std;
int n,k,num;
int accsee[50010];
struct per{
int data,cnt;
bool operator < (const per &a) const
{
if(cnt==a.cnt) return data<a.data;
else return cnt>a.cnt;
}
};
int main()
{
scanf("%d %d",&n,&k);
set<per> st;
for(int h=0;h<n;h++)
{
scanf("%d",&num);
if(h>0)
{
printf("%d:",num);
int i=0;
for(auto it=st.begin();it!=st.end();it++)
{
if(i>=k) break;
printf(" %d",it->data);
i++;
}
printf("\n");
}
if(st.find(per{num,accsee[num]})!=st.end())
st.erase(st.find(per{num,accsee[num]}));
accsee[num]++;
st.insert(per{num,accsee[num]});
}
return 0;
}
6.3 string
6.9 algorithm头文件
【例】A1141 PAT Ranking of Institutions (25 分)
ATTENTION
- PAT真的好喜欢多关键词排序[○・`Д´・ ○]
- 这道题的因素好多,没想到柳神把
tws
和ns
单独存储在了map
里!!这样就不用去找school
对应的idx了!妙妙子!!! #include <unordered_map>
不需要map
的排序功能时可以用它,快!(map
默认升值排序)
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
int n;
map<string,int> schoolToIdx;
map<int,string> idxToSchool;
struct institution{
int rank;
int nb,na,nt;
string school;
int tes;
int ns;
institution()
{
nb=na=nt=0;
ns=0;
tes=0;
}
}ins[100010];
int idx=1;
bool cmp(institution &a,institution &b)
{
if(a.tes==b.tes)
if(a.ns==b.ns) return a.school<b.school;
else return a.ns<b.ns;
else
return a.tes>b.tes;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
string id,sch;
int score;
cin>>id>>score>>sch;
//全部小写
for(int j=0;j<sch.size();j++)
if(sch[j]>='A'&&sch[j]<='Z')
sch[j]=sch[j]-'A'+'a';
//学校和idx对应
if(schoolToIdx[sch]==0)
{
ins[idx].school=sch;
schoolToIdx[sch]=idx;
idxToSchool[idx++]=sch;
}
int schIdx=schoolToIdx[sch];
if(id[0]=='A')
ins[schIdx].na+=score;
else if(id[0]=='B')
ins[schIdx].nb+=score;
else
ins[schIdx].nt+=score;
ins[schIdx].ns++;
}
for(int i=1;i<idx;i++)
ins[i].tes=(int)(ins[i].na*1.0)+(ins[i].nb/1.5)+(ins[i].nt*1.5);
sort(ins+1,ins+idx,cmp);
cout<<idx-1<<"\n";
ins[1].rank=1;
cout<<ins[1].rank<<" "<<ins[1].school<<" "<<ins[1].tes<<" "<<ins[1].ns<<"\n";
for(int i=2;i<idx;i++)
{
if(ins[i].tes==ins[i-1].tes)
ins[i].rank=ins[i-1].rank;
else
ins[i].rank=i;
cout<<ins[i].rank<<" "<<ins[i].school<<" "<<ins[i].tes<<" "<<ins[i].ns<<"\n";
}
return 0;
}
【例】A1083 List Grades (25 分)
ATTENTION
sort
函数的头文件:#include <algorithm>
vector
使用sort
函数时,使用迭代器说明排序区间。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct PER{
string name,id;
int grade;
PER(string n,string i,int g)
{
name=n;
id=i;
grade=g;
}
};
vector<PER> stu;
int n,g1,g2;
bool cmp(PER a,PER b)
{
return a.grade>b.grade;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
string s1,s2;int g;
cin>>s1>>s2>>g;
PER tmp(s1,s2,g);
stu.push_back(tmp);
}
cin>>g1>>g2;
bool flag=false;
sort(stu.begin(),stu.end(),cmp); //sort!! STL!!!
for(int i=0;i<stu.size();i++)
{
if(stu[i].grade<=g2&&stu[i].grade>=g1)
{
flag=true;
cout<<stu[i].name<<" "<<stu[i].id<<endl;
}
}
if(!flag)
cout<<"NONE";
return 0;
}
【例】A1080 Graduate Admission (30 分)
proceed v.开始
automate v.自动化
admission n.录用
national entrance exam 全国入学考试
quota n.定额; 限额; 配额
exceed v.超过
ATTENTION
- 可以直接用GE+GI作为排序的第一标尺。因为GE+GI不会超出int范围,还能避免出现小数。
sort
函数的头文件:#include <algorithm>
vector
使用sort
函数时,使用迭代器说明排序区间。- 排序函数
cmp
使用&
引用传参,可以节约时间,例如:bool cmp(peo& a, peo& b)
。 - **输出时的换行,最后一行也要有换行。**看来PAT里的题目,按行输出结果时,每一行都要换行。
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n,m,k;
int tot[110];
int curRank[110]={0}; //学校目前接收的最低名次的学生
vector<int> ans[110];
struct Stu{
int ge,gi,ave,rank;
int idx;
vector<int> choice;
Stu()
{
rank=0;
}
}stu[40010];
bool cmp(Stu a,Stu b)
{
if(a.ave==b.ave)
return a.ge>b.ge;
return a.ave>b.ave;
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
for(int i=0;i<m;i++)
scanf("%d",&tot[i]); //每个学校可以招收的人数
for(int i=0;i<n;i++)
{
scanf("%d %d",&stu[i].ge,&stu[i].gi);
stu[i].ave=(stu[i].ge+stu[i].gi)/2;
stu[i].idx=i;
for(int j=0;j<k;j++)
{
int tmp;
scanf("%d",&tmp);
stu[i].choice.push_back(tmp);
}
}
sort(stu,stu+n,cmp);
for(int i=0;i<n;i++)
{
stu[i].rank=i+1;
if(i>0&&stu[i].ave==stu[i-1].ave&&stu[i].ge==stu[i-1].ge)
{
stu[i].rank=stu[i-1].rank;
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<stu[i].choice.size();j++)
{
if(ans[stu[i].choice[j]].size()<tot[stu[i].choice[j]])
{
ans[stu[i].choice[j]].push_back(stu[i].idx);
curRank[stu[i].choice[j]]=stu[i].rank;
break;
}
else if(ans[stu[i].choice[j]].size()>=tot[stu[i].choice[j]])
{
if(stu[i].rank==curRank[stu[i].choice[j]])
{
ans[stu[i].choice[j]].push_back(stu[i].idx);
curRank[stu[i].choice[j]]=stu[i].rank;
break;
}
}
}
}
for(int i=0;i<m;i++)
{
sort(ans[i].begin(),ans[i].end());
}
for(int i=0;i<m;i++)
{
for(int j=0;j<ans[i].size();j++)
{
if(j!=ans[i].size()-1)
printf("%d ",ans[i][j]);
else
printf("%d",ans[i][j]);
}
//if(i!=m-1)
printf("\n");
}
return 0;
}
【例】A1153 Decode Registration Card of PAT (25 分)
registration n. 登记;注册;挂号
site n. 地点;位置;场所
specify vt. 指定;详细说明;列举;把…列入说明书
query n. [计] 查询
tie n.平局
ATTENTION
- 看错考场范围了呜呜呜TAT
- 白瞎了好多时间啊啊啊啊啊啊!!!
#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
struct Per{
string id;
int score;
}per[10010];
struct Site{
string s;
int cnt;
Site(){
s="000";
cnt=0;
}
}site[1010];
int n,m,type;
string term;
//座位号 人数 map怎么sort map不能sort,map本身有序
//cmp最好用引用 节约时间
bool cmp1(Per &a,Per &b)
{
if(a.score==b.score)
return a.id<b.id;
return a.score>b.score;
}
bool cmp2(Site &a,Site &b)
{
if(a.cnt==b.cnt)
return a.s<b.s;
return a.cnt>b.cnt;
}
void caseOne()
{
sort(per,per+n,cmp1);
bool flag=false;
for(int i=0;i<n;i++)
{
if(per[i].id[0]==term[0])
{
flag=true;
printf("%s %d\n",per[i].id.c_str(),per[i].score);
}
}
if(!flag) printf("NA\n");
}
void caseTwo()
{
int nt=0,ns=0;
for(int i=0;i<n;i++)
{
if(per[i].id.substr(1,3)==term)
{
nt++;
ns+=per[i].score;
}
}
if(nt==0) printf("NA\n");
else printf("%d %d\n",nt,ns);
}
void caseThree()
{
for(int i=0;i<1010;i++)
site[i].cnt=0;
bool flag=false;
for(int i=0;i<n;i++)
{
if(per[i].id.substr(4,6)==term)
{
flag=true;
int idx=(int)(per[i].id[1]-'0')*100+(int)(per[i].id[2]-'0')*10+(int)(per[i].id[3]-'0');
site[idx].cnt++;
site[idx].s=per[i].id.substr(1,3);
}
}
sort(site,site+1010,cmp2);
if(!flag) printf("NA\n");
else
{
for(int i=0;i<1010;i++)
{
if(site[i].cnt!=0)
printf("%s %d\n",site[i].s.c_str(),site[i].cnt);
}
}
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
{
cin>>per[i].id>>per[i].score;
}
for(int i=0;i<m;i++)
{
cin>>type>>term;
printf("Case %d: %d %s\n",i+1,type,term.c_str());
if(type==1)
{
caseOne();
}
else if(type==2)
{
caseTwo();
}
else if(type==3)
{
caseThree();
}
else
printf("NA\n");
}
return 0;
}