【解题报告】瑞士轮(NOIP2011普及组T3)

【题外话:这道题吧……说实话我不太喜欢……因为卡快排。】

题目不贴了,就是给你一个赛制,然后各个选手的初始得分和能力值,问你进行R轮比赛之后第Q名的编号是多少(这个编号读进来就要算OYZ,初始快排的时候也要注意。)

我是用的比较常规的方法,每次扫描整个序列,计算胜者和负者,分入两个数组,然后把这两个数组归并回原来的序列里(因为这两个序列都已经有序,所以可以免去排序直接合并),题目中要求编号小的排在前面,因为归并是稳定排序所以不需要担心这些。

其实本质来说就是个讲究技巧的模拟吧?

下贴代码,风格照样丑。

#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
ifstream fin("swiss.in");
ofstream fout("swiss.out");
struct per
{
 int fs;
 int nl;
 int bh;
};
per player[200005];
int Rs=0,ls=0,gz=0;
per winner[100005]={0},loser[100005]={0};
void Heib();
bool px(per a,per b);
int main(void)
{
 fin>>Rs>>ls>>gz;
 Rs*=2;
 for(int i=1;i<=Rs;i++)
    {
     fin>>player[i].fs;
     player[i].bh=i;
 }
 for(int i=1;i<=Rs;i++)fin>>player[i].nl;
 sort(player+1,player+Rs+1,px);
 for(int i=1;i<=ls;i++)
    {
      for(int j=1;j<=Rs;j++)
         {
          if(j%2==0)
            {
             if(player[j].bh==127||player[j-1].bh==127)
              {
     }
             if(player[j].nl>player[j-1].nl)
               {
                winner[j/2].bh=player[j].bh;
                winner[j/2].fs=player[j].fs+1;
                winner[j/2].nl=player[j].nl;
                loser[j/2].bh=player[j-1].bh;
                loser[j/2].fs=player[j-1].fs;
                loser[j/2].nl=player[j-1].nl;
               }
             else
               {
                winner[j/2].bh=player[j-1].bh;
                winner[j/2].fs=player[j-1].fs+1;
                winner[j/2].nl=player[j-1].nl;
                loser[j/2].bh=player[j].bh;
                loser[j/2].fs=player[j].fs;
                loser[j/2].nl=player[j].nl;
               }
            }
         }
     Heib();
    }
 fout<<player[gz].bh;
 return 0;
}

bool px(per a,per b)
{
 if(a.fs>b.fs)return 1;
 if(a.fs==b.fs&&a.bh<b.bh)return 1;
 if(a.fs==b.fs&&a.bh>b.bh)return 0;
 return 0;
}

void Heib()
{
 int lf=1,rt=1,zz=1;
 while(lf<=Rs/2&&rt<=Rs/2)
      {
       if(winner[lf].fs>loser[rt].fs||(winner[lf].fs==loser[rt].fs&&winner[lf].bh<loser[rt].bh))
         {
          player[zz].bh=winner[lf].bh;
          player[zz].fs=winner[lf].fs;
          player[zz].nl=winner[lf].nl;
          zz++;
          lf++;
         }
       if(winner[lf].fs<loser[rt].fs||(winner[lf].fs==loser[rt].fs&&winner[lf].bh>loser[rt].bh))
         {
          player[zz].bh=loser[rt].bh;
          player[zz].fs=loser[rt].fs;
          player[zz].nl=loser[rt].nl;
          zz++;
          rt++;
         }
      }
 while(lf<=Rs/2||rt<=Rs/2)
     {
      if(lf<=Rs/2)
        {
         player[zz].bh=winner[lf].bh;
         player[zz].fs=winner[lf].fs;
         player[zz].nl=winner[lf].nl;
         lf++;
  }
      if(rt<=Rs/2)
        {
          player[zz].bh=loser[rt].bh;
          player[zz].fs=loser[rt].fs;
          player[zz].nl=loser[rt].nl;
          rt++;
        }
     zz++;
     }
 return;
}

【题外话2:其实两篇解题报告之间我还A了几道题,不过都太简单或者太恶心到我不想写题解……OYZ】

【题外话3:这里是个准初三狗,一开学成了初三狗之后估计就不会太快更新了……】

时间: 2024-10-25 00:24:33

【解题报告】瑞士轮(NOIP2011普及组T3)的相关文章

NOIP2011 普及组 T3 洛谷P1309 瑞士轮

今天题做太少,放道小题凑数233 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长. 本题中介绍的瑞士轮赛制,因最早使用于1895年在瑞士举办的国际象棋比赛而得名.它可以看作是淘汰赛与循环赛的折衷,既保证了比赛的稳定性,又能使赛程不至于过长. 题目描述 2*N 名编号为 1~2N 的选手共进行R 轮比赛.每轮比赛开始前,以及所有比赛结束后,都

NOIP2008 普及组T3 传球游戏 解题报告-S.B.S.

题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师在此吹哨子时,传球停止,此时,拿着球没有传出去的那个同学就是败者,要给大家表演一个节目. 聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里.两种传球方法被视作不同的方法,当且仅当

NOIP2011普及组:瑞士轮

背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长. 本题中介绍的瑞士轮赛制,因最早使用于 1895 年在瑞士举办的国际象棋比赛而得名. 它可以看作是淘汰赛与循环赛的折衷,既保证了比赛的稳定性,又能使赛程不至于过长. 描述 2*N名编号为 1~2N的选手共进行R轮比赛.每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名.选手

noip2011——普及组——瑞士轮

我们先sort排个序, 然后把比一次后的赢的放进b,输的放进c, 可以保证b和c数组都是严格的降序, 然后只要把b.c合并起来就好了. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c

NOIP2011普及组 瑞士环 保序性

题目链接:http://noi.openjudge.cn/ch0401/4363/ 分析:如果直接模拟,时间复杂度是O(r*nlogn)超时 然后我们发现每次一轮开始时,刚开始是保序的,然后我们可以把所有赢得人拿出来,输的人也拿出来 发现赢得人还是保序的,输的人也是保序的,所以最终我们要干的就是把两个保序的序列合成一个保序的的序列 这样只需要排序一次,时间发杂度O(nlogn+r*n)可过 #include <iostream> #include <string.h> #inclu

NOIP2011普及组 表达式的值

题面 https://vijos.org/p/1808 看了lrj124同学的题解,使用stack来写. 题解 https://vijos.org/p/1808/solution 注意函数内部改变一个变量可能会改变另一个变量...变量会相互计算... 比如 a.zero = (a.zero*(b.zero+b.one)+a.one*b.zero)%mod; a.one = a.one*b.one%mod; 如果先赋a.one,a.zero就不对了 计算的顺序很重要

NOIP2010普及组T3 接水问题 ——S.B.S.

题目描述 学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的 供水量相等,均为 1. 现在有 n 名同学准备接水,他们的初始接水顺序已经确定.将这些同学按接水顺序从 1到 n 编号,i 号同学的接水量为 wi.接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙头接水.当其中某名同学 j 完成其接水量要求 wj后,下一名排队等候接水的同学 k马上接替 j 同学的位置开始接水.这个换人的过程是瞬间完成的,且没有任何水的浪费.即j 同学第 x 秒结束时完成接水,则

noip2011普及组T2 统计单词数(stat) KMP算法

才学了KMP,拿这题来练练手……(不过似乎有点小题大做了…… 这就是一题水水的KMP模板,匹配若干次,每一次从上次匹配后的位置开始,直到匹配失败. 虽然用的算法“高级”一点,但是居然比暴力慢了40MS啊啊啊…… Code: 1 #include<iostream> 2 using namespace std; 3 const int P=15; 4 const int S=1000005; 5 char p[P],s[S]; 6 int next[P],pl,sl; 7 void getnex

noip2011普及组——统计单词数

统计单词数 时间限制:1 s 内存限制:128MB [问题描述]一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置.注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2). [输入]输入