问题 G: Paired Up
时间限制: 1 Sec 内存限制: 128 MB题目描述
Farmer John finds that his cows are each easier to milk when they have another cow nearby for moral support. He therefore wants to take his M cows (M≤1,000,000,000, M even) and partition them into M/2 pairs. Each pair of cows will then be ushered off to a separate stall in the barn for milking. The milking in each of these M/2 stalls will take place simultaneously.
To make matters a bit complicated, each of Farmer John's cows has a different milk output. If cows of milk outputs A and B are paired up, then it takes a total of A+B units of time to milk them both.
Please help Farmer John determine the minimum possible amount of time the entire milking process will take to complete, assuming he pairs the cows up in the best possible way.
输入
输出
样例输入
3
1 8
2 5
1 2
样例输出
10
提示
Here, if the cows with outputs 8+2 are paired up, and those with outputs 5+5 are paired up, the both stalls take 10 units of time for milking. Since milking takes place simultaneously, the entire process would therefore complete after 10 units of time. Any other pairing would be sub-optimal, resulting in a stall taking more than 10 units of time to milk.
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
struct node {
ll x;// 奶牛数量
ll y;// 产奶量(时间)
}a[100010];
int cmp(node c,node d){
return c.y>d.y;
}
int main(){
int n;
//freopen("data","r",stdin);
while (scanf ("%d",&n)!=EOF){
ll maxn=-1;
for (int i=0;i<n;i++){
scanf ("%lld%lld",&a[i].x,&a[i].y);
}
sort(a,a+n,cmp);
int i=0;
int j=n-1;
ll l,r;
while (i<j){
if(a[i].x){
l=a[i].y;
}
else{
i++;
l=a[i].y;
}
if(a[j].x){
r=a[j].y;
}
else{
j--;
r=a[j].y;
}
if(a[j].x>a[i].x){// 进行优化 将左右两端和相同的跳过
a[j].x-=a[i].x;
a[i].x=0;
}
else{
a[i].x-=a[j].x;
a[j].x=0;
}
if(maxn<l+r)
maxn=l+r;
}
printf ("%lld\n",maxn);
}
return 0;
}
问题 J: 【排序】奶牛的编号
时间限制: 1 Sec 内存限制: 64 MB题目描述
有N(1≤N≤1000)头奶牛,它们都被标上一个优先等级编号:1,2或3。用来表示它们喝水时的优先次序,编号为l的最优先,编号为2的其次,编号为3的最后。每天奶牛开始时排成一行,但总是很乱,需要你把它们重新排成编号为1的奶牛在最前面,编号为2的其次,编号为3的奶牛在最后。你能计算出最少需要多少的交换次序来完成这次重排吗?
输入
第1行:1个整数N;
第2至N+I行:第i+l行有一个整数表示开始队列中第i头奶牛的编号。
输出
1行,只一个整数,表示最少需要交换次数。
样例输入
9
2
2
1
3
3
3
2
3
1
样例输出
4
提示
样例说明:有一种交换方法。
2 2 2< 1 1
2< 1 1 1 1
1< 2 2 2 2
3 3< 2 2 2
3 3 3 3< 2
3 3 3 3 3
2 2< 3 3 3
3 3 3 3 3
1 1 1< 2< 3
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[1010];
int b[1010];
int main (){
int n;
//freopen("data","r",stdin);
while(scanf("%d",&n)!=EOF){
memset(a,0,sizeof(b));
memset(b,0,sizeof(b));
for (int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a,a+n);
int sum=0;
for (int i=0;i<n;i++)
if(a[i]==b[i])
b[i]=-1;
for (int i=0;i<n;i++){
if(b[i]!=-1){
int temp=b[i];
for (int j=i;j<n;j++){
if(a[j]!=-1){
if(a[j]==temp){
if(b[j]==a[i]){
sum++;
b[i]=-1;
b[j]=-1;
break;
}
}
}
}
}
}
int sum2=0;
for (int i=0;i<n;i++){
if(b[i]!=-1)
sum2++;
}
printf ("%d\n",sum2-sum2/3+sum);
}
return 0;
}