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相互匹配,找最大值。
如:
1 | 2 | 3 | 4 | … | 97 | 98 | 99 | 100 |
---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 1 | … | 1 | 2 | 0 | 1 |
i | ||||||||
0 | 3 | 1 | 1 | … | 3 | 0 | 0 | 2 |
j |
然后找到第一个非0的数,如下:
1 | 2 | 3 | 4 | … | 97 | 98 | 99 | 100 |
---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 1 | … | 1 | 2 | 0 | 1 |
i | ||||||||
0 | 3 | 1 | 1 | … | 3 | 0 | 0 | 2 |
j |
此时配对出的数sum=i+j=2+100=102;
因为max小于sum,所以max=102;
减去i,j指针上可配对的个数,如图:
1 | 2 | 3 | 4 | … | 97 | 98 | 99 | 100 |
---|---|---|---|---|---|---|---|---|
0 | 1-1 | 2 | 1 | … | 1 | 2 | 0 | 1 |
i | ||||||||
0 | 3 | 1 | 1 | … | 3 | 0 | 0 | 2-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]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.