这篇和上篇POJ2976类似,只是多了一个保存答案,用数组保存即可。
要注意初始化,即我们二分的时候可能永远都更新不了l,即一直执行r=mid,直到退出循环,所以此时我们ans数组就不会更新,因此我们在开始的时候就要初始ans数组,以防这种情况。
例如数据 5 3 0 1 0 1 0 1 0 1 0 1,即v都是0,w都比0大,此时我们二分就将一直执行r=mid.
#include <stdio.h> #include <string.h> #include<iostream> #include <vector> #include <algorithm> #include<functional> using namespace std; typedef long long ll; #define eps 1e-6 const int N = 1e6 + 10; int n,k; int a[N],b[N]; struct node{ double val; int pos; bool operator<(const node &other)const{ return val>other.val; } }c[N]; vector<int> ans; bool check(double t) { double sum=0; for (int i = 1; i <= n; i++) c[i].val = a[i] - t*b[i],c[i].pos=i; sort(c + 1, c + n + 1); for (int i = 1; i <= k; i++) sum += c[i].val; return sum >= 0; } int main() { cin >> n >> k; for (int i = 1; i <= k; i++) ans.push_back(i); for (int i = 1; i <= n; i++) scanf("%d%d", &a[i],&b[i]); double l = 0, r = 1e7; while (r - l > eps) { double mid = (l + r) / 2; if (check(mid)) { ans.clear(); l = mid; for (int i = 1; i <= k; i++) ans.push_back(c[i].pos); } else r = mid; } if (ans.size() > 0) { for (int i = 0; i < ans.size() - 1; i++) printf("%d ", ans[i]); printf("%d", ans[ans.size() - 1]); } return 0; }