1309-瑞士轮-归并

确实是一道很好的题

(反正对我来说是的了)

在大概了解了(模糊的)思路之后

我就上手写了

纯模拟吧

每一轮就归排一次

当然时间复杂度是过不去的

(但是我是先wa的)

于是我才反思

得到了另半种种算法思路

如下:

根据题意

先把那一堆东西全输入进来

在根据初始的s值排序(这里是可以用sort的)

(这之前都很常规)

于是再循环每一轮

两两相比

把赢得放在一个数组,把输的放在一个数组

每个数组(赢输两数组)中都是降序的

在把这两个数组的每个头元素轮番比较放回原数组(和归并很类似,但比归并省了好多好多遍)

就odk了

省了好多呢

#include<iostream> 
#include<algorithm>    
using namespace std;  
int n,r,q;  
int a[200100],win[200100],los[200100];  
int s[200100],w[200100];   

bool cmp(int x,int y)  
{  
  if(s[x]==s[y])   
      return x<y;
  return s[x]>s[y];
}  

void sol()  
{  
  int i,j;  
  i=j=1,a[0]=0;  
  while(i<=win[0] && j<=los[0])  
    if(cmp(win[i],los[j]))  
      a[++a[0]]=win[i++];  
    else   
      a[++a[0]]=los[j++];  
  while(i<=win[0])
      a[++a[0]]=win[i++];  
  while(j<=los[0])
      a[++a[0]]=los[j++];          
}  
int main()  
{  
  cin>>n>>r>>q;n*=2;  
  for(int i=1;i<=n;i++)
      a[i]=i;  
  for(int i=1;i<=n;i++)
      cin>>s[i];  
  for(int i=1;i<=n;i++)
      cin>>w[i];  
  sort(a+1,a+n+1,cmp);  
  for(int i=1;i<=r;i++)  
    {  
      win[0]=los[0]=0;  
      for(int j=1;j<=n;j+=2)  
        if(w[a[j]]>w[a[j+1]])  
          {  
            s[a[j]]++;  
            win[++win[0]]=a[j];  
            los[++los[0]]=a[j+1];  
          }  
        else  
          {  
            s[a[j+1]]++;  
            win[++win[0]]=a[j+1];  
            los[++los[0]]=a[j];  
          }    
      sol();          
    }  
  cout<<a[q];
  return 0;  
}  
原文地址:https://www.cnblogs.com/darlingroot/p/10472894.html