STL题解

第k小整数

题目链接:https://nanti.jisuanke.com/t/T1670
现有 n 个正整数,要求出这 n 个正整数中的第 k 小的整数(相同大小的整数只计算一次)。
题解:set模拟

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long


int main()
{
	//IOS;
	int n,m;
	scanf("%d%d",&n,&m);
	set<int>ss; 
	for(int i=0;i<n;i++)
	{
		int x;
		scanf("%d",&x);
		ss.insert(x);
	}
		
	int cnt=0;
	int ans;
	bool flag=false;
	for(set<int>::iterator p=ss.begin();p!=ss.end();p++)
	{
		cnt++;
		if(cnt==m)
		{
			ans=(*p);
			flag=true;
			break;
		}
	}
	
	if(flag)
	{
		printf("%d\n",ans);
	}
	else
		printf("NO RESULT\n");
	return 0;
}

报数

题目链接:https://nanti.jisuanke.com/t/T1475
有 n 人围成一圈,顺序排号。从第 1个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子,问最后留下的是原来的第几号。

题解:队列模拟

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long


int main()
{
	//IOS;
	int n;
	scanf("%d",&n);
	queue<int>que;
	for(int i=1;i<=n;i++)
		que.push(i);
	
	int time=0;
	while(que.size()!=1)
	{
		time++;
		time%=3;
		int tt=que.front();
		que.pop();
		if(time==0)
			time=3;
		else
			que.push(tt);
	}
	cout<<que.front();
	return 0;
}

卡片游戏

题目链接:https://nanti.jisuanke.com/t/T1464
桌上有一叠牌,从第一张牌(即位于顶面的牌)开始从上往下依次编号为 1∼n。当至少还剩两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张放到整叠牌的最后。输入 n ,输出每次扔掉的牌,以及最后剩下的牌。
题解:队列模拟

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long


int main()
{
    //IOS;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        queue<int>que;
        for(int i=1; i<=n; i++)
            que.push(i);
        
        vector<int>ans;
        while(que.size()>1)
        {
            ans.push_back(que.front());
            que.pop();
            que.push(que.front());
            que.pop();
        }
        
        if(!que.empty())
        	ans.push_back(que.front());
        
        for(int i=0;i<ans.size();i++)
        {
        	printf("%d",ans[i]);
        	if(i!=ans.size()-1)
        		printf(" ");
        }
        printf("\n");
    }

    return 0;
}

找球号

题目链接:https://nanti.jisuanke.com/t/T1413
题意:找某一个数字是否存在,有重复数字。
题解:由于map和multiset超时,用unordered_map优化

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long


int main()
{
	//IOS;
	int n,m;
	scanf("%d%d",&n,&m);
	unordered_map<int,int>ss;
	for(int i=0;i<n;i++)
	{
		int x;
		scanf("%d",&x);
		ss[x]++;
	}
		
	for(int i=0;i<m;i++)
	{
		int x;
		scanf("%d",&x);
		if(ss.find(x)!=ss.end())
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}


Set

题目链接:https://nanti.jisuanke.com/t/T1229
现有一整数集(允许有重复元素),初始为空。我们定义如下操作:
add x 把 x 加入集合
del x 把集合中所有与 x 相等的元素删除
ask x 对集合中元素x的情况询问

对每种操作,我们要求进行如下输出。
add 输出操作后集合中 x 的个数
del 输出操作前集合中 x 的个数
ask 先输出 0 或 1 表示 x 是否曾被加入集合(0 表示不曾加入),再输出当前集合中 x 的个数,中间用空格格开。
题解:虽然题目是set,但是需要记录某一个元素的个数,则用map更方便,主要注意一下删除操作,删除某一迭代器,则该迭代器失效,不能再使用。

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long

map<int,int>mm1;
map<int,int>mm2;

int main()
{
	//IOS;
	int n;
	scanf("%d",&n);
	while(n--)
	{
		char str[6];
		int x;
		scanf("%s%d",str,&x);
		if(strcmp(str,"add")==0)
		{
			mm1[x]++;
			mm2[x]++;
			printf("%d\n",mm1[x]);
		}

		if(strcmp(str,"del")==0)
		{
			map<int,int>::iterator p=mm1.find(x);
			if(p!=mm1.end())
			{
				printf("%d\n",(*p).second);
				mm1.erase(p);
			}
			else
				printf("0\n");

		}

		if(strcmp(str,"ask")==0)
		{
			if(mm2[x]!=0)
                printf("1 %d\n",mm1[x]);
			else printf("0 0\n");
		}
	}
	return 0;
}

热血格斗场

题目:https://nanti.jisuanke.com/t/T1230
蒜头君新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。

我们假设格斗的实力可以用一个正整数表示,成为实力值。另外,每个人都有一个唯一的 id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有两个人的实力值与他差别相同,则他会选择比他弱的那个(显然,虐人必被虐好)。

不幸的是,蒜头君一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮蒜头君恢复比赛纪录,按照时间顺序依次输出每场比赛双方的 id。
题解:注意两个条件:1、id唯一无重复 2、实力值唯一无重复。用map实现:map<key,value>,key设为实力值,value设为id。需要找与某一个值的差值最小,不妨在map中先插入这个值,因为map自带排序功能,所以只要比较插入这个位置左边和右边的值与的差值即可。

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long

map<int,int>mm;

int main()
{
	//IOS;
	int n;
	scanf("%d",&n);
	mm[1000000000]=1;
	while(n--)
	{
		int id,score;
		scanf("%d%d",&id,&score);
		mm[score]=id;
		map<int,int>::iterator p=mm.find(score);
		map<int,int>::iterator p0=p;
		map<int,int>::iterator p1=p;
		
		if(p!=mm.begin())
			p0--;
		if(p!=mm.end())
			p1++;
		int len1=(*p).first-(*p0).first;
		int len2=(*p1).first-(*p).first;
		if(len1==0)
			printf("%d %d\n",(*p).second,(*p1).second);
		else if(len2==0)
			printf("%d %d\n",(*p).second,(*p0).second);
		else
		{
			if(len1<len2)
				printf("%d %d\n",(*p).second,(*p0).second);
			else if(len1>len2)
				printf("%d %d\n",(*p).second,(*p1).second);
			else
			{
				if((*p1).first<(*p0).first)
					printf("%d %d\n",(*p).second,(*p1).second);
				else
					printf("%d %d\n",(*p).second,(*p0).second);
			}
		}
	}
	return 0;
}

冷血格斗场

题目:https://nanti.jisuanke.com/t/T1231
蒜头君新开了一家冷血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。

我们假设格斗的实力可以用一个正整数表示,成为实力值,两人的实力值可以相同。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有多个人的实力值与他差别相同,则他会选择id 最小的那个。

不幸的是,蒜头君一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮蒜头君恢复比赛纪录,按照时间顺序依次输出每场比赛双方的 id。
题解:与前一个题的区别为:1、实力值可以重复 2、差值相同的情况,输出id较小的。map 内置 优先队列:map键值对<key,value> ,value 设为优先队列,存key相同的id,并且按照从小到大排列。出现相同实力差时,比较时弹出最小的id即可(优先队列top)。因为总的n没有变,所以复杂度也没变 O(nlog(n))。

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define maxm 500005
#define inf 2000000000123456789
#define IOS ios::sync_with_stdio(false)
#define ll long long

map<int,priority_queue<int,vector<int>,greater<int> > >mm;

int main()
{
	//IOS;
	int n;
	scanf("%d",&n);
	mm[1000000000].push(1);
	while(n--)
	{
		int id,score;
		scanf("%d%d",&id,&score);
		
		if(mm[score].size()>0)
		{
			printf("%d %d\n",id,mm[score].top());
			mm[score].push(id);
			continue;
		}
		
		mm[score].push(id);
		map<int,priority_queue<int,vector<int>,greater<int> > >::iterator p=mm.find(score);
		map<int,priority_queue<int,vector<int>,greater<int> > >::iterator p0=p;
		map<int,priority_queue<int,vector<int>,greater<int> > >::iterator p1=p;
		
		if(p!=mm.begin())
			p0--;
		if(p!=mm.end())
			p1++;
		int len1=(*p).first-(*p0).first;
		int len2=(*p1).first-(*p).first;
		if(len1==0)
			printf("%d %d\n",(*p).second.top(),(*p1).second.top());
		else if(len2==0)
			printf("%d %d\n",(*p).second.top(),(*p0).second.top());
		else
		{
			if(len1<len2)
				printf("%d %d\n",(*p).second.top(),(*p0).second.top());
			else if(len1>len2)
				printf("%d %d\n",(*p).second.top(),(*p1).second.top());
			else
			{
				if((*p1).second.top()<(*p0).second.top())
					printf("%d %d\n",(*p).second.top(),(*p1).second.top());
				else
					printf("%d %d\n",(*p).second.top(),(*p0).second.top());
			}
		}
	}
	return 0;
}

发布了41 篇原创文章 · 获赞 2 · 访问量 1229

猜你喜欢

转载自blog.csdn.net/qq_41418281/article/details/103109640
STL