【归并排序】wikioi 1132 瑞士轮 (noip2011)

本文探讨了如何解决OI(信息学奥赛)中的1132号问题,该问题涉及到瑞士轮比赛的计分策略。通过分析,作者提出使用归并排序作为解决方案。首先对数据进行快速排序,然后将胜利者加1分并记录在win数组中,失败者则放入lose数组。最终,通过归并操作将两个数组合并回原始数组。虽然作者最初尝试了直接快速排序的方法,但发现这会导致超时,因此强调了细节处理的重要性。

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

题目链接:http://wikioi.com/problem/1132/

          http://cojs.tk/cogs/problem/problem.php?pid=625

         https://www.vijos.org/p/1771

分析:

首先有一个不断快排的做法,好像会超时。

正解是归并。

先快排一次。

之后就是归并排序。

先将胜利的人加上1分,并放入一个win数组。

将失败的人放入一个lose数组里。

最后归并到原数组中。

这个题原本想到了正解,但是倒在了细节上。。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,r,q,i,j,ji;
struct node
{
	int s,p,ii;
}a[200010],w[100010],l[100010];

bool cmp(node a,node b)
{
	if (a.s==b.s) return a.ii<b.ii;
	return a.s>b.s;
}
int main()
{  
	freopen("swiss.in","r",stdin);
	freopen("swiss.out","w",stdout);
	cin>>n>>r>>q; n*=2;
	for ( i=1;i<=n;++i) scanf("%d",&a[i].s),a[i].ii=i;
	for ( j=1;j<=n;++j) scanf("%d",&a[j].p);
	sort(a+1,a+1+n,cmp);
	for ( ji=1;ji<=r;ji++)
	 {  
	    int wi=1,lo=1;
	 	for ( i=1;i<=n;i+=2)
	 	{
	 		if (a[i].p<a[i+1].p) w[wi++]=a[i+1],l[lo++]=a[i]; 
	 		else if (a[i].p>a[i+1].p)l[lo++]=a[i+1],w[wi++]=a[i];
	 	}
	 	wi--;lo--;
	 	for ( i=1;i<=n/2;i++) w[i].s++;
	 	int x=1,y=1;
	 	i=0;
		while( x<=n/2 && y<=n/2)
	 	{
	 		if (w[x].s>l[y].s) a[++i]=w[x++];
	 	    if (w[x].s<l[y].s) a[++i]=l[y++];
			if (w[x].s==l[y].s&&w[x].ii>l[y].ii) a[++i]=l[y++];
	 		if (w[x].s==l[y].s&&w[x].ii<l[y].ii) a[++i]=w[x++];
		 }
		 if (x>n/2) 
		while (y<=n/2) a[++i]=l[y++];      
		else while (x<=n/2) a[++i]=w[x++];
	 }
	 printf("%d",a[q].ii);
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值