您的位置:首页 > 其它

poj之旅——2976

2016-04-04 15:47 288 查看
思路:依然需要确定一个贪心策略,每次贪心地去掉那些对正确率贡献小的考试。如何确定某个考试[a_i, b_i]对总体准确率x的贡献呢?a_i / b_i肯定是不行的,不然例子里的[0,1]会首当其冲被刷掉。在当前准确率为x的情况下,这场考试“额外”对的题目数量是a_i – x
* b_i,当然这个值有正有负,恰好可以作为“贡献度”的测量。于是利用这个给考试排个降序,后k个刷掉就行了。

程序:(切不可直接复制)

var

  n,k,i,l,r,mid:longint;

  a,b:array[0..110000]of longint;

procedure qsort(x,l,r:longint);

var

  mm,i,j,xx,t:longint;

begin

  i:=l;j:=r;mm:=(l+r)shr 1;

  xx:=a[mm]-x*b[mm];

  repeat

    while a[i]-x*b[i]>xx do i:=i+1;

    while a[j]-x*b[j]<xx do j:=j-1;

    if i<=j then

     begin

       t:=a[i];a[i]:=a[j];a[j]:=t;

       t:=b[i];b[i]:=b[j];b[j]:=t;

       i:=i+1;j:=j-1;

     end;

  until i>j;

  if i<r then qsort(x,i,r);

  if j>l then qsort(x,l,j);

end;

function check(x:longint):boolean;

var

  sa,sb,i:longint;

begin

  qsort(x,1,n);

  sa:=0;sb:=0;

  for i:=1 to n-k do

   begin

     sa:=sa+a[i];sb:=sb+b[i];

   end;

  exit(sa/sb>x);

end;

begin

  readln(n,k);

  while (n+k>0) do

   begin

     for i:=1 to n do begin read(a[i]);a[i]:=a[i]*100000;end;

     for i:=1 to n do read(b[i]);

     l:=0;r:=100000;

     while l<=r do

      begin

        mid:=(l+r)shr 1;

        if check(mid) then l:=mid+1

         else r:=mid-1;

      end;

     writeln(round(l/1000));

     readln(n,k);

   end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: