欢迎来到我的算法与代码笔记(建设中)

在这里记录学习之旅,分享编程心得,用二次元的活力激发灵感!

开始阅读

随笔标题一

简要摘要介绍,方便读者快速了解文章主要内容。

随笔标题二

简要摘要介绍,方便读者快速了解文章主要内容。

神使(二分答案)

问题 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;
}
posted @   bakul  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示