TOJ 3622. Perfect Matching

 问题描述:给定两个长度为N的序列A 和 B,要求每个A 中的数和B中的一个数做乘积(每个数只使用一次),找出一种搭配使得最大

                     的数最小。

解法:分类讨论,设a_pos , a_neg , a_zero , b_pos , b_neg , b_zero分别为A和B中正数,负数和0的个数,则

             1)如果( a_pos > b_neg + b_zero || a_neg > b_pos + b_zero )结果为正数。

             2)如果( a_zero == 0 && b_zero == 0 && a_pos == b_pos && a_neg == b_neg) 结果为负数

             3)否则结果为0

             对于1),设A的正数多,我们这样考虑,其中一个序列的正数多于另一个的负数与0之和,所以搭配的时候一定是A的所有

 负数和0与B的正数搭配,A的所有正数除了与B的所有负数搭配外,还要和B的一部分正数搭配,所以只需两个序列按相反排序。

 比如可以对A升序排列,对B降序排列,然后就可以找最大的了。

              对于2),很明显需要A的所有正数于B的负数搭配,A的负数与B的正数搭配,而两者的绝对值要尽量小,所以可以对A升序

排序,对于 B,正数部分升序排,负数部分也是升序排,但整体降序排,即前部分是正数,后部分是负数。举个例子:

                             A:-5,4,-2,2,-3,3

                             B:2,-1,3,-2,-3,1

排序后因该是:

                             A:-5,-3,-2, 2,  3,  4

                             B: 1, 2, 3, -3,-2, -1

 这样就能保证最大的数最小。

             对于3),结果即为0.

 #include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3ffffff #define MAXN 100002 using namespace std; typedef long long LL; int a[MAXN],b[MAXN]; bool cmp(const int a,const int b){ return a > b; } bool cmp2(const int a,const int b){ return a < b; } bool cmp3(const int a,const int b){ if(a > 0 && b > 0) return a < b; else if(a < 0 && b < 0) return a < b; else return a > b; } int main() { int n,a_pos,a_neg,a_zero,b_pos,b_neg,b_zero; while(scanf("%d",&n) != EOF){ a_pos = a_neg = a_zero = 0; b_pos = b_neg = b_zero = 0; for(int i= 1;i <= n; ++i){ scanf("%d",&a[i]); if(a[i] > 0) a_pos++; else if(a[i] == 0) a_zero ++; else a_neg ++; } for(int i = 1;i <= n; ++i){ scanf("%d",&b[i]); if(b[i] > 0) b_pos ++; else if(b[i] == 0) b_zero ++; else b_neg ++; } LL ans; if(a_pos > b_neg+b_zero || a_neg > b_pos+b_zero){ //结果为正 sort(a+1,a+1+n,cmp); sort(b+1,b+1+n,cmp2); ans = 0; for(int i = 1;i <= n; ++i){ if((LL)a[i]*b[i] > ans) ans = (LL)a[i]*b[i]; } } else if(a_zero == 0 && b_zero == 0 && a_pos == b_neg && a_neg == b_pos){ //结果为负 sort(a+1,a+1+n,cmp2); sort(b+1,b+1+n,cmp3); ans = (LL)a[1]*b[1]; for(int i = 1;i <= n; ++i){ if((LL)a[i]*b[i] > ans) ans = (LL)a[i]*b[i]; } } else //结果为0 ans = 0; printf("%lld/n",ans); } }

你可能感兴趣的:(TOJ 3622. Perfect Matching)