【洛谷 P1309】 【归并排序】 瑞士轮

【洛谷 P1309】 【归并排序】 瑞士轮

题目

在这里插入图片描述
在这里插入图片描述


解题思路

先快排将选手的初始得分排序
每一轮都给赢者和输者分成两个队列
给赢者加分
因为本来的序列就是降序的,所以分裂后的两个队列也是降序的
利用归并排序的思想将两个队列合并
得出每一轮结束后的排名


代码

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
struct lzf{
    
    
	int f,n,w;
}a[200010],temp[200010],win[200010],lose[200010];
int n,q,r,len1,len2;
bool cmp(lzf f,lzf t)
{
    
    
	 if (f.f==t.f)
	    return f.w<t.w;
		else return f.f>t.f;
}  //快排,从大到小
void merge()
{
    
      
	 int i=1,j=1,c=1; 
	 while (i<=len1&&j<=len2)
	 {
    
    
	 	   if ((win[i].f>lose[j].f)||(win[i].f==lose[j].f&&win[i].w<lose[j].w))   
			  a[c++]=win[i++];
	 	      else a[c++]=lose[j++];
	 }
	 while (i<=len1) a[c++]=win[i++];
	 while (j<=len2) a[c++]=lose[j++]; 
}  //合并
int main()
{
    
    
	scanf("%d%d%d",&n,&r,&q);
	for (int i=1;i<=2*n;i++)
	{
    
    
	    a[i].w=i;
	    scanf("%d",&a[i].f);
	}
	for (int i=1;i<=2*n;i++)
	    scanf("%d",&a[i].n);
	sort(a+1,a+2*n+1,cmp); 
	for (int i=1;i<=r;i++)
	{
    
    
		len1=len2=0;
		for (int j=1;j<=n;j++)
		    if (a[2*j-1].n>a[2*j].n)  //加分以及分组
		    {
    
    
		       a[2*j-1].f++;
		       win[++len1]=a[2*j-1]; 
		       lose[++len2]=a[2*j];
		    }
		       else {
    
    
		           a[2*j].f++;
		           win[++len1]=a[2*j];
		           lose[++len2]=a[2*j-1];
		           }
		merge();
	} 
	printf("%d",a[q].w);  //输出排名所对应的位置
}

猜你喜欢

转载自blog.csdn.net/qq_45621109/article/details/115415604
今日推荐