小闪最近迷上了二刀流——不过他耍的其实是剑——新买了一个宝库用来专门存放自己收集的双剑。一对剑有两把,分只能左手用的和只能右手用的,各自有一个攻击力数值。虽然一对剑在小闪刚拿到时是一对,不过其实可以认为它们是独立的两把剑。一对剑的攻击力是左右两把剑的攻击力之和,小闪可以自由地搭配左右剑来练习二刀流。每次小闪得到一对新的双剑,他都可以去更新一次自己的双剑宝库,重新给每把剑配对。 小闪需要自己给每一把剑配对,然后他的智能宝库会提供宝库中攻击力最高的一对剑来给小闪练习;不过小闪其实是一个很低调的人,不喜欢锋芒毕露,希望自己练习时的双剑攻击力尽可能小——虽然不知道怎么改变宝库,但是他可以改变双剑的搭配。每次新得到一对剑,更新完宝库之后,小闪练习时用的剑可能就会发生变化。 请你求出每次更新宝库后小闪练习二刀流时的双剑攻击力。
Input
输入包含不超过10组数据。 对于每组数据,第一行一个整数N(1<=N<=100000),表示小闪前后共收集到了N对双剑;接下来N行,每行包含两个整数A和B(1<=A,B<=100),分别表示每次小闪收集到的一对剑的左手用剑和右手用剑的攻击力数值。 每组数据之后会有一个空行。 输入以一行一个整数0结束。
Output
对于每组数据,输出N行,每行一个整数,表示每次更新后小闪练习二刀流时的双剑攻击力值。 相邻两组数据之间输出一个空行。
Sample Input
3
2 8
3 1
1 4
3
1 1
2 2
3 3
0
Sample Output
10
10
9
2
3
Input
输入包含不超过10组数据。 对于每组数据,第一行一个整数N(1<=N<=100000),表示小闪前后共收集到了N对双剑;接下来N行,每行包含两个整数A和B(1<=A,B<=100),分别表示每次小闪收集到的一对剑的左手用剑和右手用剑的攻击力数值。 每组数据之后会有一个空行。 输入以一行一个整数0结束。
Output
对于每组数据,输出N行,每行一个整数,表示每次更新后小闪练习二刀流时的双剑攻击力值。 相邻两组数据之间输出一个空行。
Sample Input
3
2 8
3 1
1 4
3
1 1
2 2
3 3
0
Sample Output
10
10
9
2
3
4
题目大意:找到最大值的最小值
解题思路:贪心。将一个序列变成正序,一个变成逆序。然后将两个序列相加。题目的关键是怎么得到当前输入的序列的正序与逆序,如果用快排,n*nlogn超时。
在这里,我们可以用到桶排序,因为a,b的值都在100以内。
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int N=105;
int n,a[N],b[N];
int main()
{
int x,y;
int flag=0;
while(~scanf("%d",&n)&&n)
{
if(flag)
printf("\n");
flag=1;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0; i<n; i++)
{
scanf("%d%d",&x,&y);
++a[x];//桶排序
++b[y];
int l=0,r=100;
int ans=-1;
int cntl=a[l],cntr=b[r];//当前a序列中l的个数,b序列中r的个数
while(l<=100&&r>=0)
{
if(cntl&&cntr)//个数都不为0
{
ans=max(ans,l+r);
}
if(cntl==cntr)//个数相等
{
l++;//a往下走
r--;//b往下走
cntl=a[l];//重新赋值
cntr=b[r];
continue;
}
if(cntl<cntr)//个数不相等,小的往下走
{
l++;
cntr-=cntl;
cntl=a[l];
}
else if(cntr<cntl)
{
r--;
cntl-=cntr;
cntr=b[r];
}
}
printf("%d\n",ans);
}
}
return 0;
}