高老师和李老师上完课在从良乡回中关村的校车上很无聊,就开始打起来了扑克牌。
高老师有 n 张卡牌,李老师有 m 张卡牌。高老师打算把他的卡牌藏起来一张,然后李老师挑了一张高老师没有藏起来的卡牌和一张他自己的卡牌组成一对。最终得分为两张卡牌数值的乘积。高老师想让得分尽可能的小,李老师而想让得分尽可能的大。两个老师都很聪明,具有透视眼,会根据当前状态做出最优选择,想知道最后的得分会是多少?
输入描述
输入数据第一行输入 T [1,10] 表示数据组数。
对于每一组数据的第一行,输入两个正整数n,m [2,100 000]。
接下来一行有个n数代表高老师的n张牌,
接下来一行有个m数代表李老师的m张牌。[-10^9,10^9]
输出描述
对于每组数据输出一行一个数字,代表最终得分。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 153600KB | 0 |
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAX 100005
long long f[MAX],s[MAX];
void merge(long long b[],long long n1,long long c[],long long n2,long long a[],long long n)
{
long long i=0,j=0,k=0,u;
while(i<n1&&j<n2)
{
if(b[i]<=c[j])
{
a[k]=b[i];
i++;
}
else
{
a[k]=c[j];
j++;
}
k++;
}
if(i==n1)
{
for(u=k;u<n;u++,j++) a[u]=c[j];
}
else
{
for(u=k;u<n;u++,i++) a[u]=b[i];
}
}
void mergesort(long long a[],long long n)
{
long long i;
long long n1,n2;
n1=floor((float)n/2);
n2=ceil((float)n/2);
if(n>1)
{
long long b[n1],c[n2];
for(i=0;i<n1;i++) b[i]=a[i];
for(i=0;i<n2;i++) c[i]=a[i+n1];
mergesort(b,n1);
mergesort(c,n2);
merge(b,n1,c,n2,a,n);
}
}
long long largest(long long a,long long b,long long c,long long d)
{
long long q[4]={a,b,c,d};
mergesort(q,4);
if(q[3]==a) return 1;
else if(q[3]==b) return 2;
else if(q[3]==c) return 3;
else if(q[3]==d) return 4;
}
int main()
{
long long t;
scanf("%lld",&t);
long long choose,res;
long long n,m;
while(t--)
{
scanf("%lld %lld",&n,&m);
for(int i=0;i<n;++i) scanf("%lld",&s[i]); //先手藏牌
for(int i=0;i<m;++i) scanf("%lld",&f[i]);
mergesort(s,n);
mergesort(f,m);
choose = largest(s[0]*f[0],s[0]*f[m-1],s[n-1]*f[0],s[n-1]*f[m-1]);
switch(choose)
{
case 1: s[0]=s[1]; break;
case 2: s[0]=s[1]; break;
case 3: s[n-1]=s[n-2]; break;
case 4: s[n-1]=s[n-2]; break;
}
choose = largest(s[0]*f[0],s[0]*f[m-1],s[n-1]*f[0],s[n-1]*f[m-1]);
switch(choose)
{
case 1: res=s[0]*f[0]; break;
case 2: res=s[0]*f[m-1]; break;
case 3: res=s[n-1]*f[0]; break;
case 4: res=s[n-1]*f[m-1]; break;
}
printf("%lld\n",res); //必须lld
}
}