• 【二分答案】BTP职业网球赛


    版权声明:本篇随笔版权归作者Etta(http://www.cnblogs.com/Etta/)所有,转载请保留原地址!

    Description

    参加职业网球赛的奶牛们有着职业牛网球赛协会(BTP)的排名。
    有时候,预测一场网球赛的结果是可能的。
    如果参赛的两头牛排名之间的差距大于一个给定的常数K(0<=K<=N-1),即|Rank1-Rank2|>K(其中Rank1,Rank2分别表示奶牛1与奶牛2的排名),那么排名较高的奶牛总是会赢得比赛的胜利。
    下周将有一个大型的淘汰赛制的赛事,有N(N=2^t,t<=16,t∈N)头奶牛参赛,产生一个冠军。在第一轮,N/2对选手进行比赛,获胜的N/2个选手进入下一轮。
    同样,下面的每轮比赛中,都是获胜的一半进入下一轮,直到只剩一头牛。
    场外的牛们在对比赛下赌注,想知道随着一轮一轮的比赛,最后有可能夺冠的牛中排名最低的牛的排名。
    你的工作就是计算这个最低排名,并且给出一种能使这头牛获胜的场次安排。

    Input

    第1行:两个空格隔开的数N和K。

    Output

    一行一个整数,即所有可能夺冠的牛中排名最低的牛的排名。

    Sample Input

    16 3

    Sample Output

    11

    Solution  

      可以证明如果排名为X的选手最终获胜,那么排名在X前的选手也可以获胜(详见论文杨俊《浅谈二分策略的应用》)。所以可以开心地二分答案了,用并查集倒推比赛序列判断答案是否可行。

    Code

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 using namespace std;
     5 
     6 const int A=500010;
     7 
     8 int n,k,t,r,l,p,q,ss,tot,tmp;
     9 int ex[A],nxt[A],line[A];//nxt[]表示从i起未被刷的奶牛
    10 
    11 int find(int x)
    12 {
    13     if(x!=nxt[x])nxt[x]=find(nxt[x]);
    14     return nxt[x];
    15 }
    16 
    17 bool pan(int R)
    18 {
    19     for(int i=1;i<=n+1;++i)nxt[i]=i;//循环至n+1保证当方案不可行时能够判断
    20     nxt[R]=R+1;
    21     tot=ss=1;
    22     line[tot]=R;
    23     
    24     for(int i=1;i<=t;++i)
    25     {
    26         for(int j=1;j<=ss;++j)
    27         {
    28             p=line[j];
    29             q=find(max(1,p-k));
    30             if(q>n)return false;
    31             nxt[q]=nxt[q+1];
    32             line[++tot]=q;
    33         }
    34         ss=tot;//细节
    35     }
    36     return true;
    37 }
    38 
    39 void erfen(int l,int r)
    40 {
    41     int mid;
    42     while(l!=r)
    43     {
    44         mid=((l+r)>>1)+1;
    45         if(pan(mid))l=mid;
    46         else r=mid-1;
    47     }
    48     printf("%d
    ",l);
    49 }
    50 
    51 int main()
    52 {
    53     freopen("competition.in","r",stdin);
    54     freopen("competition.out","w",stdout);
    55     scanf("%d%d",&n,&k);
    56     tmp=n;
    57     while(!(tmp&1)){tmp>>=1;++t;}//计算log以2为底n的对数
    58     l=1;r=n;
    59     erfen(l,r);
    60     return 0;
    61 }
  • 相关阅读:
    我的第一个B2C 网上图书商店,初始化
    JFreeChat学习圆饼状图的创建(结合serlvet,非原创)!
    JFreeChat学习柱状图的创建(X,Y轴的口口问题还未解决,固暂时使用拼音表示)
    JFreeChat学习柱状图关于 口口 的进一步解决方案
    JSON发送的工具类分享,应该还是蛮常用的!
    linux 常见命令
    mysql常用命令
    php 实现树状无限分类查询
    轻量级的mvc框架封装
    lamp 环境下,php7.0以上,配置重写rewrite,影藏index.php
  • 原文地址:https://www.cnblogs.com/Etta/p/6368155.html
Copyright © 2020-2023  润新知