基础实验7-2.1 魔法优惠券 (25分)
在火星上有个魔法商店,提供魔法优惠券。每个优惠劵上印有一个整数面值K,表示若你在购买某商品时使用这张优惠劵,可以得到K倍该商品价值的回报!该商店还免费赠送一些有价值的商品,但是如果你在领取免费赠品的时候使用面值为正的优惠劵,则必须倒贴给商店K倍该商品价值的金额…… 但是不要紧,还有面值为负的优惠劵可以用!(真是神奇的火星)
例如,给定一组优惠劵,面值分别为1、2、4、-1;对应一组商品,价值为火星币M$7、6、-2、-3,其中负的价值表示该商品是免费赠品。我们可以将优惠劵3用在商品1上,得到M$28的回报;优惠劵2用在商品2上,得到M$12的回报;优惠劵4用在商品4上,得到M$3的回报。但是如果一不小心把优惠劵3用在商品4上,你必须倒贴给商店M$12。同样,当你一不小心把优惠劵4用在商品1上,你必须倒贴给商店M$7。
规定每张优惠券和每件商品都只能最多被使用一次,求你可以得到的最大回报。
输入格式:
输入有两行。第一行首先给出优惠劵的个数N,随后给出N个优惠劵的整数面值。第二行首先给出商品的个数M,随后给出M个商品的整数价值。N和M在[1, 106]之间,所有的数据大小不超过230,数字间以空格分隔。
输出格式:
输出可以得到的最大回报。
输入样例:
4 1 2 4 -1
4 7 6 -2 -3
输出样例:
43
用堆排序将优惠券和商品价值按升序排序。
从前往后,优惠券和商品价值均为正的,乘积累加在sum中;
从后往前,优惠券和商品价值均为负的,乘积累加在sum中。
样例中43=74+62+(-1)*(-3)
C语言实现:
#include <stdio.h>
#include <stdlib.h>
void Swap(int * A, int * B)
{
int t;
t = *A;
*A = *B;
*B = t;
}
void Heap(int * A, int root, int N);//堆排序
int main()
{
int i, j;
int N, M;
int * Q, *S;
scanf("%d", &N);
Q = (int *)malloc(N * sizeof(int));
for (i = 0; i < N; i++)//优惠券存入Q数组内
{
scanf("%d", &Q[i]);
}
scanf("%d", &M);
S = (int *)malloc(M * sizeof(int));
for (i = 0; i < M; i++)//商品价值存入S数组内
{
scanf("%d", &S[i]);
}
int PosQ = 0, PosS = 0, Pos = 0;//Q中正数有PosQ个,S中正数有PosS个
int NegQ = 0, NegS = 0, Neg = 0;//Q中负数有NegQ个,S中负数有NegS个
for (i = 0; i < N; i++)
{
if (Q[i] > 0)
{
PosQ++;
}
else if (Q[i] < 0)
{
NegQ++;
}
}
for (i = 0; i < M; i++)
{
if (S[i] > 0)
{
PosS++;
}
else if (S[i] < 0)
{
NegS++;
}
}
if (PosQ <= PosS) { Pos = PosQ; }
else { Pos = PosS; }
if (NegQ <= NegS) { Neg = NegQ; }
else { Neg = NegS; }
int sum = 0;
for (i = N / 2; i >= 0; i--)//建立最大堆
{
Heap(Q, i, N);
}
for (i = N - 1; i >= 0; i--)//堆排序
{
Swap(Q + 0, Q + i);
Heap(Q, 0, i);
}
for (i = M / 2; i >= 0; i--)//建立最大堆
{
Heap(S, i, M);
}
for (i = M - 1; i >= 0; i--)//堆排序
{
Swap(S + 0, S + i);
Heap(S, 0, i);
}
//调试
/*
for (i = 0; i < N; i++)
{
printf("%d ", Q[i]);
}
printf("\n");
for (i = 0; i < M; i++)
{
printf("%d ", S[i]);
}
printf("\n");
*/
//
for (i = N - Pos, j = M - Pos; i < N, j < M; i++, j++)
{
sum = sum + Q[i] * S[j];
}
for (i = 0, j = 0; i < Neg, j < Neg; i++, j++)
{
sum = sum + Q[i] * S[j];
}
printf("%d", sum);
return 0;
}
void Heap(int * A, int root, int N)
{
int parent, child;
int X = A[root];
for (parent = root; 2 * parent + 1 < N; parent = child)
{
child = 2 * parent + 1;
if (child + 1 < N&&A[child] < A[child + 1])
{
child++;
}
if (X < A[child])
{
A[parent] = A[child];
}
else
{
break;
}
}
A[parent] = X;
}