CodeForces 356A - Knight Tournament

本文介绍了一种解决骑士竞赛问题的高效算法。通过使用Set数据结构进行区间操作来记录骑士间的胜负关系,避免了暴力求解可能导致的时间超限问题。文章详细展示了如何利用Set的特性实现快速查找与删除操作,确保每个骑士的状态只被更新一次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目背景和大致意思是,王国要举行骑士比赛。
骑士编号从1—N;开始给定骑士的数目和比赛的场数。
接着每一行给定一个区间L和R,和一个骑士编号X,区间L—R里面的人都被X击败。
骑士被击败以后就出局,不在继续参加。
最后输出每个人是谁击败的他,如果没人击败他,那么他肯定赢到最后,是冠军,输出0;


这道题数据范围很大,每次都是区间操作,如果暴力去做,肯定会超时。
分析以下,一旦 一个人被击败过,那么他肯定不会再出现。
这有点想Set的性质,每个元素只会出现一次,且可以随意删除。
于是这道题目可以用Set做,每次给定一个区间,删除这个区间里面的所有数字,当然删除过的不会再删除。

给删除的人标记击败他们的人,最后输出一个数组,保存击败他们的人的编号。


看到有人说不能直接删除,于是先标记在删除。

但是好像直接删除并没有影响。不是很清楚Set的原理

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
#include<set>
using namespace std;

set<int> s;
set<int>::iterator it,k,tmp[1000005];
int a[1000005];
int n,m,num;
int l,r,x;
int main()
{
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		s.clear();
		memset(a,0,sizeof(a));
		for(i=1;i<=n;i++)
			s.insert(i);
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&l,&r,&x);
			k=s.lower_bound(l);//二分查找找第一个大于等于L的数字
			num=0;
			for(it=k;*it<=r&&it!=s.end();it++)
			{
				if(*it!=x)
				{
					a[*it]=x;
					tmp[num++]=it;
				}
			}
			for(j=0;j<num;j++)//先标记再删除
				s.erase(tmp[j]);
		}
		for(i=1;i<n;i++)
			printf("%d ",a[i]);
		printf("%d\n",a[n]);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值