神使(二分答案)

news/2025/3/1 1:24:35/文章来源:https://www.cnblogs.com/bakul/p/18744405

问题 C: 神使

题目描述

在一个神秘的王国里,有一位伟大的勇者正在寻找他的最佳战斗伙伴。王国里有n个勇士,每个勇士的战斗力值记为ai。勇者决定通过一场淘汰赛来选择最终的战斗伙伴,比赛规则如下:

竞技场将进行n-1轮投票淘汰,每轮淘汰一个勇士。
在每一轮中,第i个勇士会将自己的一票投给与自己战斗力值差距最大的勇士,即找到j,使得|ai-aj|最大。此轮得票最多的勇士将被淘汰。
如果有多个勇士得票相同,战斗力值较大的勇士优先被淘汰。
如果第i个勇士在本轮中有多个差距相同的候选目标,他会优先投票给战斗力值较大的勇士。
勇者想知道,在所有轮次结束后,剩下的勇士是谁。

保证所有勇士战力值不同

输入

第一行包含一个整数n,表示有n个勇士。

第二行包含n个整数,第i个整数ai表示第i个勇士的战斗力值。

输出

输出一行一个整数,表示最终剩下的勇士的编号。

样例输入

5
2 3 6 1 10

样例输出

4

提示

对于30%的数据,满足 n≤20,0≤ai≤1000
对于50%的数据,满足n≤5000,0≤ai≤10^5
对于100%的数据,满足n≤10,-109≤ai≤109

分析

从直观上我们应该选择数据稀疏的一边的边界淘汰掉,怎么刻画数据的稀疏呢?我们可以想到,边界之间的值一个界点,分界点左边离右边边界远,全投给右边,左边类似,那么怎么精确刻画呢?对于v[0]v[n-1],如果<=(v[0]+v[n-1])/2的数据数量更多,那么右边界值应该淘汰,如果两边一样多,也舍弃右边界值,反之,淘汰左边界值,那么只要重复到只有最后一个值就可以了,那么可以使用双指针,使用upper_bound()求区间大于中间值的索引,然后算两边的数量。
我的错误:1)搞错lower_bound()的功能,是求大于等于的值 2)求数量上搞错计算的边界

代码

#include <bits/stdc++.h>
#include <iostream>
#define de(x) cout << #x << " = " << (x) << endl;
#define de2(x,y) cout << #x << " = " << (x) << " " << #y << " = " << (y) << endl;
#define de3(x,y,z) cout << #x << " = " << (x) << " " << #y << " = " << (y )<< " " << #z << " = " << (z) << endl;
#define f(i,a,b) for(int i = a;i < b;++i)
#define fd(i,a,b) for(int i = a;i >= b;--i)
#define fro for
#define mem(a) memset(a,0,sizeof(a))typedef long long ll;
typedef unsigned long long ull;
using namespace std;
//
// string l_plus(string a, string b)
// {
//     vector<int> n(10000,0);
//     vector<int> m(10000,0);
//     vector<int> sum(10000,0);
//
//     int la = a.size();
//     int lb = b.size();
//
//     for(int i = la - 1;i >= 0;--i)
//     {
//         n[la-i-1] = a[i] - '0';
//         //de(i);
//     }
//     for(int i = lb - 1;i >= 0;--i)
//     {
//         m[lb-i-1] = b[i] - '0';
//         //de(i);
//     }
//
//     //add
//     ll add = 0;
//     int len = max(la, lb);
//     for(int i = 0;i < len;++i)
//     {
//         sum[i] = n[i] + m[i] + add;
//         add = sum[i]/10;
//         sum[i] %= 10;
//         //cout << sum[i] << " ";
//
//     }
//     if(add!= 0)
//     {
//         sum[len] = add;
//         len++;
//         //de(len);
//     }
//
//     string res = "";
//     for(int i = len -1;i >= 0;--i)
//     {
//         char ch = sum[i] + '0';
//         res += ch;
//         //de(ch);
//     }
//     //cout << res;
//
//     return res;
// }// string L_Subtraction(string s1,string s2)
// {
//     bool neg = false;
//     int len1 = s1.size(),len2 = s2.size();
//     if(len1 < len2 || s1 < s2)//符号判定
//     {
//         neg = true;
//         swap(s1,s2);
//         swap(len1,len2);
//     }
//     vector<int> a1(len1,0),a2(len1,0),ans(len1,0);//特别注意,算减法的时候会访问到len1的长度,小心a2越界!!!
//     for(int i = 0;i < len1;++i)
//     {
//         a1[i] = s1[len1 - 1 - i]  - '0';
//     }
//
//     for(int i = 0;i < len2;++i)
//     {
//         a2[i] = s2[len2 - 1 - i]  - '0';
//     }
//
//     for(int i = 0;i < len1;++i)
//     {
//         int temp = a1[i] - a2[i];
//         if(temp< 0)
//         {
//             temp += 10;
//             a1[i+1]--;
//         }
//         ans[i] = temp;//别忘了
//     }
//
//     string anss = "";
//     if(neg)
//         anss = "-" + anss;
//     int i = len1-1;//len1-1是最末尾,小心越界
//     for(;i > 0 && ans[i]==0;++i);
//
//     for(;i >= 0;--i)
//     {
//         anss += ans[i] + '0';
//     }
//     return anss;
// }//
// string h_mult_l(string s1,string s2)
// {
//     int len = s1.size();
//     long long a = stoi(s2);
//     vector<long long> ans(len + s2.size(),0);
//     for(int i = 0;i < len ;++i)
//     {
//         long long temp = 1LL * (s1[len - 1 - i] - '0') * a;
//         ans[i] += temp;//注意处理顺序
//         ans[i+1] += ans[i]/10;//当前位一共的进位
//         ans[i] %= 10;//最后处理当前位
//     }
//     if(ans[len] >= 10)//注意多余进位
//     {
//         int le = len;
//         long long t = ans[len];
//         while (t)
//         {
//             ans[le++] = t%10;
//             t/= 10;
//         }
//     }
//     string res = "";
//     int i = len + s2.size() - 1;
//     for(;i > 0 && ans[i] == 0;--i);
//     for(;i >= 0;--i)
//     {
//         res += ans[i] + '0';
//     }
//     return res;
// }//
// string h_mult_h(string s1,string s2)
// {
//     int len1 = s1.size(),len2 = s2.size();
//     vector<int> a1(len1,0),a2(len2,0),ans(len1+len2+1,0);
//     for(int i = 0;i < len1;++i)
//     {
//         a1[i] = s1[len1 - 1 - i] - '0';
//     }
//     for(int i = 0;i < len2;++i)
//     {
//         a2[i] = s2[len2 - 1 - i] - '0';
//     }
//     for(int i = 0;i < len1;++i)
//     {
//         for(int j = 0;j < len2;++j)
//         {
//             ans[i+j] += a1[i] * a2[j];
//             ans[i+j+1] += ans[i+j]/10;
//             ans[i+j] %= 10;
//         }
//     }
//     if(ans[len1 + len2 - 1] > 10)
//     {
//         ans[len1 + len2] = ans[len1 + len2 -1]/10;
//         ans[len1 + len2 - 1] %= 10;
//     }
//     string res = "";
//     int i = len1 + len2;
//     for(;i > 0 && ans[i] == 0;--i);
//     for(;i >= 0;--i)
//     {
//         res += ans[i] + '0';
//     }
//     return res;
//
//
// }// int n,m,e;
// vector<vector<int>> g; // 邻接矩阵
// vector<bool> vis;      // 标记当前遍历中是否访问过
// vector<int> linked;    // 每个右侧点匹配的左侧点
// bool dfs(int x)
// {
//     for(int i = 1;i <= m;++i)
//     {
//         if(g[x][i] && !vis[i])
//         {
//             vis[i] = true;// 标记为已访问
//             if(linked[i] == -1 || dfs(linked[i]))// 匹配点为空或递归找到增广路
//             {
//                 linked[i] = x;// 更新匹配关系
//                 return true;
//             }
//         }
//
//     }
//
//     return false;
// }//链式向前星
//
// int n,m,s;
// const int N = 1000100;
// int dis[N];
// struct eage
// {
//     int to, dis, next;
// };
// int cnt = 0;
// int head[N];
// eage e[N];
// bool vis[N];
//
// void add_edge(int from,int tod, int w)
// {
//     cnt++;
//     e[cnt].to = tod;
//     e[cnt].dis = w;
//     e[cnt].next = head[from];
//     head[from] = cnt;
// }// int fa[30005];
// void init()
// {
//     for(int i = 1;i <= 30000;++i) fa[i] = i;
// }
// int finds(int x)
// {
//     if(fa[x] == x) return x;
//     else return finds(fa[x]);
// }
// void <bvtag class="memorize_new_word bv_icpc_upc_edu_cn bv_browserName_google_chrome  burning_vocabulary  _id_1737264440897">merge</bvtag>(int x,int y)
// {
//     fa[finds(x)] = finds(y);
// }#define int long long
struct cow {int id,val;bool operator < (const cow a) const {return val < a.val;}bool operator > (const cow a) const {return val > a.val;}
};
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);//// freopen("E:/Code/C++/untitled1/input.txt","r",stdin);// freopen("output.txt","w",stdout);int n;cin >> n;vector<cow> v(n);for (int i = 0;i < n;++i) cin >> v[i].val,v[i].id= i+1;sort(v.begin(),v.end());int l = 0,r = n-1;while (l < r) {cow mid;mid.val = v[l].val+v[r].val>>1;                            int nub = upper_bound(v.begin()+l,v.begin()+r,mid) - (v.begin()); //算真正的索引,不是相对的if ((nub-l)>=r-nub+1) r--;                                          //使用实例测试一下怎么算的else l++;}cout << v[r].id;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/891421.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm使用中有关环境变量、解释器、虚拟环境的梳理

一、环境变量系统变量和用户变量: 计算机优先查找系统变量,如果没有,才查找用户变量。这种安排便于多用户的管理。PATH变量的优先级: 自上而下,优先级越来越低,这种顺序可以更改如图当用户在终端输入python时,计算机则会优先到F:\env\Python3.13\目录下寻找python解释器…

【CodeForces训练记录】Codeforces Round 1007 (Div. 2)

训练情况赛后反思 放假降智了,逆天卡 A 题,还 WA 了一发,放假就会掉大分 TAT A题 打表易得结论,直接手动枚举几个,发现有循环节,第 \(1,4,7,\cdots\) 可以为观众,其他都不可以点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusi…

wustctf2020_getshell_2

看到shell函数,可以直接找sh字符ROPgadget --binary wustctf2020_getshell_2 --string "sh"算一下可以发现只溢出返回地址的后一个exp from pwn import * context.log_level=debug io = remote(node5.buuoj.cn,29807) sh=0x08048670 call_sys=0x08048529 payload=cy…

web开发 辅助学习管理系统开发日记 day5

第五天 坚持就是胜利 Q1:在开发条件分页查询的时候要在controller层把所有的变量类型全都生命出来,注意类型不要声明错误,我因为把Localdate 写成了localdatetime 直接让我找了半个小时bug。 在传递日期参数的时候可以用@DateTimeFormat 的注解指定前端传递日期的格式 Q2:在…

【杭电多校训练记录】2025钉耙编程中国大学生算法设计春季联赛 - 热身赛

训练情况赛后反思 有幸抢到了签到题的一血,据说是去年杭电新生赛,题面写的很神秘,简单题差点不会做了,还被卡常TLE了一发 1008 金牌 签到题,统计Au数量和Ag、Cu数量,因为Ag和Cu能合出来一个Au,所以答案是 Au+min(Ag,cu)点击查看代码 #include <bits/stdc++.h> #de…

k8s部署dashboard kubepi

1. KubePi 简介KubePi 是一个开源的 Kubernetes 多集群管理面板,提供以下核心功能: 多集群管理:支持接入多个 Kubernetes 集群统一管理。 可视化操作:提供资源(Pod、Deployment、Service 等)的创建、删除、监控功能。 权限控制:基于角色的访问控制(RBAC),支持多租户隔…

强大数定律与弱大数定律的区别

先来讲一下弱大数定律吧,这个比较好理解 弱大数定律的标准形式是这样的: \[\forall \epsilon>0,\underset{n\rightarrow\infty}{\lim}P(|\bar{X}_n-\mu|<\epsilon)=1 \]这里注意的是我们的极限符号是包含概率的,我们按照数列极限的定义将其写开: \[\forall \epsilon&…

分布式锁—1.原理算法和使用建议

大纲 1.Redis分布式锁的8大问题 2.Redis的RedLock算法分析 3.基于Redis和zk的分布式锁实现原理 4.Redis分布式锁的问题以及使用建议1.Redis分布式锁的8大问题 (1)非原子操作(set+lua) (2)忘了释放锁(手动+超时) (3)释放了其他线程的锁(lua+唯一值) (4)加锁失败的处理(自旋+睡眠…

理解Rust引用及其生命周期标识(上)

写在前面 作为Rust开发者,你是否还没有完全理解引用及其生命周期?是否处于教程一看就会,但在实际开发过程中不知所措?本文将由浅入深,手把手教你彻底理解Rust引用与生命周期。 关于本文的理解门槛 本文主要面向的是已经基本上了解过Rust这门语言,对引用以及生命周期(及其…

TCP/IP协议栈相关知识

为什么提出TCP/IP参考模型OSI参考模型比较复杂TCP和IP两大协议在网络上广泛使用 三种参考模型如今用的最多的是TCP/IP五层模型,而OSI七层模型更多用于学习。 TCP/IP常见协议要了解协议对应的传输层端口号,因为计算机是通过端口号分辨所使用的是那种协议。 应用层要了解常见协…

Vulkan环境配置 | vscode+msvc 解决方案

Vulkan环境配置 | vscode+msvc 解决方案 前言 如果作为Windows 11侠的你是一个vscode爱好者,凑巧电脑上还安装有Visual Studio,这个时候你突然想配置一个Vulkan开发环境。作为minimalist的你可不希望在电脑上安装任何额外的组件,那么这篇安装指南一定适合你。 准备工作 你需…

mysql索引原理简单说明

本次使用的是mysql5.7.17 首先说下索引中的组合索引,即多个字段组合的索引就叫做组合索引,但是什么时候会生效,什么时候会失效,我不是很清楚 首先建个表造点数据看下情况,CREATE TABLE `bank` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT 主键,`bank_end` VARCHAR…