最小最大和

Description

  Alice和Bob在玩一个游戏,每一轮Bob都会给Alice两个整数A和B(1<=A,B<=100),Alice每一轮必须把目前所有的A序列和B序列中的数一一配对,每个数必须用且只使用一次,要求最大和最小。

Input

  第一行一个整数N(1<=N<=100000),表示比赛的轮数。
  接下来N行每行包含两个整数A和B(1<=A,B<=100),表示Bob这一轮给的两个数。

Output

  输出N行,每行输出最小的最大和。

Sample Input

输入1:

3

2 8

3 1

1 4

输入2:

3

1 1

2 2

3 3

Sample Output

输出1:

10

10

9

输出2:

2

3

4

Data Constraint

Hint

【样例解释】
  样例1中,第一轮的A序列为{2},B序列为{8},只能是(2,8),答案为10;
  第二轮A序列为{2,3},B序列{8,1},可以采用配对(2,8),(1,3),这样的配对最大的和是10,是最小的配对方案;
  第三轮A序列为{2,3,1},B序列为{8,1,4}可以采用配对(2,1),(3,4),(1,8),最大的和为9,没有比这更小的配对方案。
【数据范围】
  50%的数据N<=200

【题目解释】

应该也不用解释什么了吧?就是把a这串数从小到大排序后,再把b从大到小排序,然后把a[i]与b[i]相互匹配,匹配时记录最大值就可以了。

【题解】

但上述的方法无疑会超时,于是我们找其他的方法来做。
我们可以发现这里写图片描述那么我们就可以想一想从这里入手,再想一想,因为我们要把大的数和小的数相加,于是我们可以a,b分别放入两个桶x,y中然后用两个指针l,r分别指在x的头和y的尾。
然后l,r相互匹配,找最大值。
如:

1234979899100
01211201
i
03113002
j

然后找到第一个非0的数,如下:

1234979899100
01211201
i
03113002
j

此时配对出的数sum=i+j=2+100=102;
因为max小于sum,所以max=102;
减去i,j指针上可配对的个数,如图:

1234979899100
01-1211201
i
03113002-1
j

不断这样做,直到i,j都走完了就可以输出答案了。

var
    a,b,q,p:array[1..100] of longint;
    x,y,i,l,r,n,s,k,max:longint;
begin
    assign(input,'the_max_and_the_min.in');reset(input);
    assign(output,'the_max_and_the_min.out');rewrite(output);
    readln(n);
    for i:=1 to n do
    begin
        readln(x,y);
        inc(q[x]);
        inc(p[y]);
        l:=1;r:=100;
        max:=0;s:=s+2;
        k:=s;a:=q;b:=p;
        while k>0 do
        begin
            while (a[l]=0) and (l<101) do inc(l);
            while (b[r]=0) and (r>0) do dec(r);
            if l+r>max then max:=l+r;
            if a[l]>b[r] then
            begin
                dec(k,2*b[r]);
                a[l]:=a[l]-b[r];
                b[r]:=0;
            end else
            if a[l]<b[r] then
            begin
                dec(k,2*a[l]);
                b[r]:=b[r]-a[l];
                a[l]:=0;
            end else
            begin
                dec(k,2*a[l]);
                a[l]:=0;
                b[r]:=0;
            end;
        end;
        writeln(max);
    end;
    close(input);close(output);
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值