1037 Magic Coupon

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1037 Magic Coupon相关的知识,希望对你有一定的参考价值。

1. 贪心算法题,贪心策略:两组乘子相乘,每个数字至多用一次,希望得到最大的乘积。那么让A组绝对值最大的正数和B组最绝对值最大的正数相乘,次大的和次大的相乘……同样的让A组绝对值最大的负数和B组绝对值最大的负数相乘,次大的和次大的相乘,绝不发生正数和负数相乘的情况。0由于对结果没影响,不做考虑。

2.具体实施时,在读数据的时候就分别记下A组和B组各自的正数个数、负数个数,相乘时正数和负数分开,取A,B中较小的正数个数作为正数相乘的组数,取A,B中较小的负数个数作为负数相乘的组数。对两个数组进行从大到小排序。

3.这题比较碰巧的地方在于,由于从大到小排序,正数绝对值大到小是从前到后分布,负数绝对值大到小是从后往前分布,由于又知道各自的组数,因而遍历起来很清晰。

AC代码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;

const int maxn = 100010;
const int INF = 1000000000;//INF:下确界  SUP:上确界 
const double eps = 1e-3;

bool cmp(int a,int b){
	return a>b;
} 

int main(){
	int cobj[maxn],pobj[maxn];
	
	int nc,np;//二者没有本质区别
	
	scanf("%d",&nc);
	
	int cobjMoreZero = 0;//数组cobj大于0的数字个数
	int cobjLessZero = 0;//数组cobj小于0的数字个数 
	  
	for(int i=0;i<nc;i++){
		scanf("%d",&cobj[i]);
		if(cobj[i]<0)cobjLessZero++;
		if(cobj[i]>0)cobjMoreZero++;
	}
	
	scanf("%d",&np);
	
	int pobjMoreZero = 0;
	int pobjLessZero = 0;
	
	for(int i=0;i<np;i++){
		scanf("%d",&pobj[i]);
		if(pobj[i]<0)pobjLessZero++;
		if(pobj[i]>0)pobjMoreZero++;
	}
	
	//对两个数组进行从大到小排序 
	sort(cobj,cobj+nc,cmp);
	sort(pobj,pobj+np,cmp);
	
	long long res = 0;
	
	for(int i=0;i<min(cobjMoreZero,pobjMoreZero);i++){
		res += cobj[i]*pobj[i];
	}
	
	for(int i=0;i<min(cobjLessZero,cobjLessZero);i++){
		res += cobj[nc-1-i]*pobj[np-1-i];
	}
	
	printf("%lld",res);
	
	 

	return 0;
}

以上是关于1037 Magic Coupon的主要内容,如果未能解决你的问题,请参考以下文章

1037 Magic Coupon (25 分)

PAT1037. Magic Coupon (25)

PAT Advanced 1037 Magic Coupon (25) [贪?算法]

PAT (Advanced Level) 1037. Magic Coupon (25)

1037 Magic Coupon (25 分)难度: 简单 / 知识点: 排序 贪心

1037 Magic Coupon