B - K-th Number HDU - 6231 (二分 尺取)
WindowsSource 2017中国大学生程序设计竞赛-哈尔滨站
题意
给一个数组,在所有长度大于等于k的区间内,找出第 大的数,放到另一个数组中,然后在新数组中找到第M大的数。
思路
二分答案,每次二分的时候我们得到一个x
对于每个x 利用尺取,得到 第K大的数大于等于x 的区间一共有多少个
代码1
二分下标
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1e6 + 10; const int mod = 1e9+7; int a[N]; int b[N]; int n,k,m; //求 第K大的数大于等于x 的区间一共有多少个 int check(int x){ int ans=0; int num=0;//j-i之间 大于x的数 的数量 int j=1; for(int i=1;i<=n;i++){ if(a[i]>=x) num++; if(num==k){ ans+=n-i+1; while(a[j]<x){ ans+=n-i+1; j++; } num--,j++; } } return ans; } void solve(){ cin>>n>>k>>m; for(int i=1;i<=n;i++) cin>>a[i] , b[i]=a[i]; sort(b+1,b+n+1); int l=1,r=n; int ans=0; while(l<=r){ int mid=l+r>>1; int x=check(b[mid]); if(x==m){ ans=mid; break; } else if(x>m){ ans=mid; l=mid+1; } else r=mid-1; } cout<<b[ans]<<endl; } signed main() { int t; cin>>t; while(t--) solve(); return 0; }
代码2
也可以 直接二分数
#include <bits/stdc++.h> using namespace std; typedef long long ll; int N,K; ll M; int a[100005]; bool judge(int x){ ll ans = 0; int num = 0; int j = 1; for(int i = 1; i <= N; i++){ if(a[i] >= x) num++; if(num == K){ ans += N - i + 1; while(a[j] < x){ ans += N - i + 1; j++; } num--; j++; } } if(ans >= M) return true; else return false; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d%lld",&N,&K,&M); for(int i = 1; i <= N; i++){ scanf("%d",&a[i]); } int l = 1,r = 1000000000; int m; while(l < r){ m = l + r >> 1; if(judge(m)) l = m + 1; else r = m; } printf("%d\n",l-1); } return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16859254.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
,
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-11-04 xxxx