A Compatible Pair(CodeForces 934A)

欢迎访问https://blog.csdn.net/lxt_Lucia~~

宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~dalao们点个关注呗~~

本题为考核3中的E题,我用的这个方法思维还算比较独特,不过正因为独特了一丢丢,倒是也挺快A了,但是也一直在想这种方法会不会有特殊情况过不去...不过经过一段时间的思考和讨论,到目前为止并未发现不对,题目后台的测试样例也比较大,想了想也无非就那么几种情况,不会有其他。如果有发现不对的,或者有其他思路的,欢迎小哥哥小姐姐随时私聊我哦~


A. A Compatible Pair

Nian is a monster which lives deep in the oceans. Once a year, it shows up on the land, devouring livestock and even people. In order to keep the monster away, people fill their villages with red colour, light, and cracking noise, all of which frighten the monster out of coming.

Little Tommy has n lanterns and Big Banban has m lanterns. Tommy's lanterns have brightness a1, a2, ..., an, and Banban's have brightness b1, b2, ..., bm respectively.

Tommy intends to hide one of his lanterns, then Banban picks one of Tommy's non-hidden lanterns and one of his own lanterns to form a pair. The pair's brightness will be the product of the brightness of two lanterns.

Tommy wants to make the product as small as possible, while Banban tries to make it as large as possible.

You are asked to find the brightness of the chosen pair if both of them choose optimally.

Input

The first line contains two space-separated integers n and m (2 ≤ n, m ≤ 50).

The second line contains n space-separated integers a1, a2, ..., an.

The third line contains m space-separated integers b1, b2, ..., bm.

All the integers range from  - 109 to 109.

Output

Print a single integer — the brightness of the chosen pair.

Examples

input

2 2
20 18
2 14

output

252

input

5 3
-1 0 1 2 3
-1 0 1

output

2

题意:

        Tommy有 n 个灯笼,大班班有灯笼。汤米的灯具有亮度a1,a2,...,an,而Banban的亮度分别为亮度b1,b2,...,bm。Tommy打算藏一个灯笼,然后Banban选择Tommy的一个没藏起来的灯笼和一个他自己的灯笼组成一对。这对灯笼的亮度将是两个灯笼亮度的乘积。Tommy想让乘积尽可能小,而Banban试图让乘积尽可能大。

注意:

看到这里,提示一下很多同学容易犯的小错误。

1.没有考虑负数的情况,有不少同学以为Tommy一定会隐藏自己数值最大的来使结果最小,但实际上并不一定,举个栗子,Tommy的a数组为a[0]=1,a[1]=123,Banban的b数组为b[0]= -123,b[1]= -1,那么Tommy想让结果最小,一定不会选择隐藏a[1]=123,而是隐藏a[0]=1,如果看到这里发现你是因为这个错了,请先不要继续往下看,继续根据自己的思路完成此题再回来看吧。

2.数据比较大,我开了long long int。

3.按照两个数组分别为正数组,负数组,正负综合数组分类讨论的方法非常容易漏掉情况,既麻烦又易错。还好当时多想了一下,想到了下面这种方法,要不也得多WA几发...... 哈哈~为下文作铺垫埋伏笔啦~

 思路:

         这里就先介绍一下我的思路吧,仅供参考。问题的关键就在于,Tommy是选择了“掐头”还是“去尾”,我们先把a,b两个数组快排,然后用a数组的头(a[0])和尾(a[n-1])与b数组的头(b[0])和尾(b[m-1])分别交叉相乘,存到结构体c[4]中,z表示对应的乘积,num记录一下该乘积是由a数组的头还是尾得到的(便于后面判断Tommy隐藏了哪个)。将c数组按照z的值快排取最大,即可知道Tommy隐藏了哪个灯笼。后面就可分为两大类,隐藏了a[0]和隐藏了a[n-1],然后再用相同的方法交叉相乘,此时无需再记录隐藏灯笼的下标,也无需再增设数组,直接覆盖结构体中z的值即可。唯一需要注意的就是,若隐藏a[0],则a数组“掐头”,带入计算的a[0]要替换为a[1],同理若隐藏a[n-1],则a数组“去尾”,带入计算的a[n-1]要替换为a[n-2]。最后再将c数组按z快排,即可得出最后结果。嗯 magic~~~

略略略~上代码: 

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<stdlib.h>

using namespace std;

struct qwe{
    long long int z;   //记录相对应的乘积
    int num;           //记录该乘积是由a数组中的头还是尾得到的
}c[4];                 //记录a,b两数组头和尾交叉相乘得到的结果

bool cmp(struct qwe x,struct qwe y){
    return x.z<y.z;
}

int main()
{
    long long int n,m,i;
    scanf("%lld%lld",&n,&m);
    long long int a[n],b[m];
    for(i=0;i<=n-1;i++)
        scanf("%lld",&a[i]);
    for(i=0;i<=m-1;i++)
        scanf("%lld",&b[i]);
    sort(a,a+n);         //将a数组快排
    sort(b,b+m);         //将b数组快排
    c[0].z=a[0]*b[0];
    c[0].num=0;
    c[1].z=a[0]*b[m-1];
    c[1].num=0;
    c[2].z=a[n-1]*b[0];
    c[2].num=n-1;
    c[3].z=a[n-1]*b[m-1];
    c[3].num=n-1;        //分别计算a,b头和尾交叉相乘的结果,num作好记录
    sort(c,c+4,cmp);     //将c数组快排,则c[3]为乘积最大值,num就是Tommy隐藏灯笼的下标
    if(c[3].num!=0)      //隐藏了a[n-1]
    {
        c[0].z=a[0]*b[0];
        c[1].z=a[0]*b[m-1];
        c[2].z=a[n-2]*b[0];
        c[3].z=a[n-2]*b[m-1];
    }
    else                //隐藏了a[0]
    {
        c[0].z=a[1]*b[0];
        c[1].z=a[1]*b[m-1];
        c[2].z=a[n-1]*b[0];
        c[3].z=a[n-1]*b[m-1];
    }
    sort(c,c+4,cmp);    //将c数组快排
    printf("%lld\n",c[3].z);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lxt_lucia/article/details/81067235