解题思路
- 两堆数字,有正负,各取一个,乘积为正,则得到乘积数目的钱;乘积为负,则需要付这么多钱
- 每个数字只能选一次,0不使用
- 目的:赢最多的钱
- 两个序列中最大的正数与最大的正数乘,最小的负数与最小的负数乘
- 如果只有一个数列有负数,就不适用负数;正数也是如此
所有数不超过2^30 int, 但是乘积可能超过
代码平铺直叙,其实也没啥看头
AC代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100010; // 数列不超过10^5个数
int nc[maxn], np[maxn];
int main() {
int a, b;
scanf("%d", &a);
for (int i = 0; i < a; i++) {
scanf("%d", &nc[i]);
}
scanf("%d", &b);
for (int i = 0; i < b; i++) {
scanf("%d", &np[i]);
}
double money = 0;
int l1, l2, h1, h2;
l1 = l2 = h1 = h2 = 0;
sort(nc, nc + a);
sort(np, np + b);
while (nc[l1] < 0) l1++; // 0~l1-1为负数,h1~a-1为正数
if (nc[l1] == 0) h1 = l1 + 1; //略过0
else h1 = l1;
while (np[l2] < 0) l2++; // 0~l2-1为负数,h2~b-1为正数
if (np[l2] == 0) h2 = l2 + 1; //略过0
else h2 = l2;
int minp = min(l1, l2); // 负数循环加的次数
int i = 0, j = 0;
while(i < l1 && j < l2)
money += nc[i++] * np[j++];
i = h1, j = h2;
a--; b--;
while(a >= i && b >= j)
money += nc[a--] * np[b--];
printf("%.0f", money);
return 0;
}