打败魔人布欧以后,孙悟空收了n个徒弟,每个徒弟战斗力各不相同。他教导所有的徒弟和体术,合体后战斗力为原战斗力相乘。任何两个徒弟都可以合体,所以一共有n*(n-1)/2种合体徒弟。有一天,他想考验一下孙悟天战斗力如何,希望在所有n*(n-1)/2种合体徒弟中选择战斗力第k高的,与孙悟天对战。可是孙悟空徒弟太多了,他已然懵逼,于是找到了你,请你帮他找到对的人。
打败魔人布欧以后,孙悟空收了n个徒弟,每个徒弟战斗力各不相同。他教导所有的徒弟和体术,合体后战斗力为原战斗力相乘。任何两个徒弟都可以合体,所以一共有n*(n-1)/2种合体徒弟。有一天,他想考验一下孙悟天战斗力如何,希望在所有n*(n-1)/2种合体徒弟中选择战斗力第k高的,与孙悟天对战。可是孙悟空徒弟太多了,他已然懵逼,于是找到了你,请你帮他找到对的人。
第一行两个int。徒弟数量:n <= 1*10^6;战斗力排名:k <= n*(n-1)/2
第二行空格分隔n个int,表示每个徒弟的战斗力。
战斗力排名k的合体徒弟战斗力。
5 2 1 3 4 5 9
36
// 二分答案,然后再去找答案。思路和9月1号pdd最后一道类似。 #include <iostream> #include <cstring> #include <cmath> #include <vector> #include <algorithm> #include <vector> #include <list> #include <stack> #include <string> #include <set> #include <queue> #include <climits> #include <unordered_set> #include <map> #include <iostream> #include <algorithm> #include <cstring> #include <unordered_map> #include <map> using namespace std; typedef long long LL; const int mod = 1e9+7; using namespace std; const int inf = 0x7f7f7f7f; #define _for(i,l,r) for(int i=(l);i<(r);i++) LL data[1000005]; int main() { LL n,k; scanf("%lld%lld",&n,&k); _for(i,0,n){ scanf("%lld",&data[i]); } sort(data,data + n); LL l = data[0] * data[1], r = data[n - 1] * data[n - 2]; k = n * (n - 1) / 2 - k + 1; while(r > l){ LL mid = (l + r) / 2; LL cnt = 0; for(LL i = n - 1;i>=0 ;i--){ LL tmp = mid / data[i]; if(i) { LL index = upper_bound(data, data + i, tmp) - data; cnt += index; } } if(cnt >= k){ r = mid; }else{ l = mid + 1; } } LL t = LLONG_MIN; // cout << " l : "<< l << endl; for(LL i = 1;i<n;i++){ LL tmp = l / data[i]; LL index = upper_bound(data, data + i, tmp) - data; t = max(t,data[i] * data[index - 1]); } cout << t << endl; return 0; }
#include <bits/stdc++.h> using namespace std; long long check(vector<long long>& att, long long& mid, long long k, long long n) { long long below = 0; long long num = 0; long long same_p = 0; long long min_val = att[n - 1] * att[n - 1] * 2; for (long long i = 0; i < n; i++) { long long pos = upper_bound(att.begin() + i + 1, att.end(), mid / att[i]) - att.begin(); num += att.size() - pos; if (pos == att.size()) continue; long long minu = att[pos] * att[i] - mid; if (minu < min_val) { min_val = minu; below = att[pos] * att[i]; same_p = 0; } if(minu == min_val) same_p++; } if(k == num || (num > k && num-same_p < k)) { mid = below; num = k; } return num; } int main() { long long n,k; vector<long long> att; scanf("%lld %lld", &n, &k); long long tmp; for (long long i = 0; i < n; i++) { scanf("%lld", &tmp); att.push_back(tmp); } sort(att.begin(), att.end()); long long lo = att[0] * att[1]; long long hi = att[n - 1] * att[n - 2]; long long ans; while (lo <= hi) { long long mid = (lo + hi) >> 1; long long num = check(att, mid, k, n); if (num == k) { ans = mid; break; } if (num > k) { lo = mid + 1; } else hi = mid - 1; } printf("%lld\n", ans); return 0; }AC
n, k = list(map(int, input().split())) nums = list(map(int, input().split())) nums.sort() def upper_bound(nums, target): low, high = 0, len(nums)-1 pos = len(nums) while low<high: mid=(low+high) // 2 if nums[mid]<=target: low = mid+1 else:#> high = mid pos = high if nums[low]>target: pos = low return pos def Smaller(x): cnt = 0 for i in range(len(nums) - 1): cnt += len(nums[i+1:]) - upper_bound(nums[i+1:], x // nums[i]) if cnt >= k: return True return False low, high = nums[0] * nums[1], nums[-1] * nums[-2] while low < high: mid = (low + high) // 2 if Smaller(mid): low = mid + 1 else: high = mid print(high)
#include <cstdio> #include <vector> #include <algorithm> using namespace std; int main() { long n, k; scanf("%ld%ld", &n, &k); vector<long> A(n); for (int i = 0; i < n; ++i) scanf("%ld", &A[i]); sort(A.begin(), A.end()); long left = 1, right = A[n-1]*A[n-2]; while (left<=right) { long mid = (left+right)/2; long count = 0; int i = 0, j = n-1; while (i < j && count < k) { while (i < j && A[i]*A[j]<mid) i++; count += j-i; j--; } if (count >= k) left = mid+1; else right = mid-1; } printf("%ld\n", right); return 0; }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner scan = new Scanner(System.in); int n = scan.nextInt(); long k = scan.nextLong(); long[] power = new long[n]; for(int i=0;i<n;i++){ power[i] = scan.nextLong(); } Arrays.sort(power); long l = 1,r = power[n-1]*power[n-2],mid = 0; while(l<r){ mid = (l+r+1)/2; long cnt = 0; int left = 0, right = n-1; while(left<right && cnt<k){ while(power[left]*power[right]<mid) left++; cnt+=Math.max(right-left,0); right--; } if(cnt>=k) l=mid; else r = mid-1; } System.out.println(l); } }
n,k = map(int,input().split()) t = list(map(int,input().split())) print(sorted([t[i]*t[j] for i in range(n-1) for j in range(i+1,n)])[-k])
nk = list(map(int,input().split())) n = nk[0] k = nk[1] fight = sorted(list(map(int,input().split()))) res = [] for i in range(0, n-1): for j in range(i+1, n): num = fight[i] * fight[j] res.append(num) res = sorted(res, reverse = True) print(res[k - 1]) 65%,我觉得不能用暴力求解,应该是找到第K个直接结束循环
nk = list(map(int,input().split())) n = nk[0] k = nk[1] fight = sorted(list(map(int,input().split()))) res = [] for i in range(0, n): for j in range(1, i): num = fight[i] * fight[j] res.append(num) res = sorted(res, reverse = True) print(res[k - 1])