【PAT】第六章 C++标准模板库介绍(例题)

第六章 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真的好喜欢多关键词排序[○・`Д´・ ○]
  • 这道题的因素好多,没想到柳神把twsns单独存储在了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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值