Regionals 2014 >> South Pacific

来源:互联网 发布:mac 查找文件夹命令 编辑:程序博客网 时间:2024/06/11 00:31


题意:给出n只袜子和一个k,每只袜子的长度不同。求两只袜子相差值从小到大第k位的袜子是哪两只。

思路:虽然题目给了20s,粗算之下暴力不会超时,然而数组是很多组的,所以纯暴力会超时。于是就想到了二分袜子的差值,本题对于数据的处理很苛刻,是一道卡时的好题。


#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<vector>#include<cmath>#include<map>#include<algorithm>using namespace std;typedef long long ll;ll num[100005];int n;ll k;ll cal(int mid){  //计算两数相差小于等于mid的情况数总和 int i = 0,j = 1;ll cnt = 0;ll tot = 0;while(i < n){if(j<n && num[j]-num[i]<=mid){j ++;cnt ++;}else{tot += cnt;   cnt = cnt-1;  //num[j]到num[i]之差小于等于mid的有cnt个,那么num[i+1]到num[j]的有cnt-1个 i ++;}}return tot;}int main(){while(~scanf("%d%lld", &n, &k)){if(!n && !k) break;for(int i = 0;i < n;i++) scanf("%lld", num+i);sort(num,num+n);ll l = 1,r = 1000000009;   //二分两数之差,找到小于等于此差的情况数恰好大于k的时候 while(l < r){ll mid = (l+r)>>1;ll tot = cal(mid);if(tot < k) l = mid+1;else r = mid;}ll rest = k-cal(r-1);  //两数相减为r的情况中,所求答案位于第几位 int i = 0,j = 1;ll cnt = 0;while(i < n){if(!rest) break;if(j<n && num[j]-num[i]<=r){if(num[j]-num[i] == r){rest --;if(!rest) printf("%lld %lld\n", num[i], num[j]);}j ++;}else {i++;}}/*int flag = 0;for(int i = 0;i < n;i++){if(flag) break;for(int j = i+1;j < n;j++){if(num[j]-num[i] == r){rest --;if(!rest){flag = 1;printf("%d %d\n", num[i], num[j]);break;}}}}*/}    return 0;}



0 0