神使(二分答案)
问题 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; #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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现