农夫约翰发现,当他的奶牛在附近有另一头奶牛获得道德支持时候,他就更容易挤牛奶了。因此,他想把他的M头奶牛(M<1000 000 000,M是偶数)分割为M/2对。然后,每一对将被引到谷仓里的一个单独的小隔间里挤奶。每一个隔间的挤牛奶将同时进行。
让事情变得有点复杂的是,每一个农夫约翰的奶牛都有不同的产奶量。如果奶牛产奶量是A和B,那么就需要用A+B的时间来给它们挤奶。输入格式:
第一行为一个正整数N(1≤N≤100,000)
接下来有N行,每行两个正整数x和y,表示有x头奶牛的产奶量为y。保证所有x的总和等于M (1≤y≤1,000,000,000)
思路:因为要时间最小,所以根据贪心思想,从小到大排序,每次区间头尾相加,取最大值即可。
值得注意的是,这题m太大,用数组把每个数存下来再排序显然无法实现,所以采用结构体。
#include<bits/stdc++.h>
using namespace std;
struct cow
{
int x;
long long y;
}a[100005];
int n;
bool mycmp(cow a,cow b)
{
return(a.y<b.y);
}//按y值排序。
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y;
sort(a+1,a+n+1,mycmp);
long long minn=0;
int topp=1,bott=n;//topp指向头,bott指向尾。
while(topp<=bott)//之所以取等号,是因为有可能出现要相加的数位于同一个集合中。
{
long long summ=a[topp].y+a[bott].y;
if(summ>minn) minn=summ;//比较。其实变量不该声明为minn,误导了自己很久。根据木桶原理,是求(最小值中的)最大值……
if(a[topp].x>a[bott].x) //如果第topp个集合的元素个数>第bott个集合的元素个数,那么bott指向上一个集合。
{
a[topp].x-=a[bott].x;
bott--;
}else
if(a[topp].x<a[bott].x)//小于则topp指向下一个集合。
{
a[bott].x-=a[topp].x;
topp++;
}else//如果相等,那么头尾两个指针都往中间移。
{
topp++;bott--;
}
}
cout<<minn;
return 0;
}
最近太颓,初赛总结另写吧。