魔法优惠券(排序)
[问题描述]
在火星上有个魔法商店,通过魔法优惠券。每个优惠券上印有一个整数面值K,表示若你在购买某商品使用这张优惠券,可以得到K倍该商品价值的回报。该商店还免费赠送一些有价值的商品,但如果你在领取免费赠品的时候使用面值为正的优惠券,则必须倒贴给商品K倍该商品价值的金额……但是不要紧,还有面值为负的优惠券可以用。
例如,给定一组优惠券,面值分别为1、2、4、-1;对应一组商品,价值为火星币7、6、-2、-3,其中负的价值表示该商品是免费赠品。我们可以将优惠券3(面值4)用在商品1(价值7)上,得到火星币28的回报。优惠券4(面值-1)用在商品4(价值-3)上,得到火星币3的回报。但是,如果一不小心把优惠券3(面值4)用到商品4(价值-3)上,你必须倒贴给商店火星币12个。同样,把优惠券4(面值-1)用到商品1(价值7)上,你必须倒贴给商店火星币7个。
规定每张优惠券和每件商品都只能最多被使用一次,求你可以得到的最大回报。
[基本要求]
(1)输入说明:输入有两行。第一行首先给出优惠券的个数N,随后给出N个优惠券的整数面值。 第二行首先给出商品的个数M,随后给出M个商品的整数价值。N和M在[1,106]之间,所有的数据大小不超过230,数字间以空格分隔。
(2)输出说明:输出可以得到的最大回报。
(3)测试用例:
输入 4 1 2 4 -1
4 7 6 -2 -3
输出 43
输入:4 3 2 6 1
3 2 6 3
输出:49
输入: 7 3 36 -1 73 2 3 6
6 -1 -1 -1 -1 -1 -1
输出: 1
数据结构
四个数组
int *coupin, *goods;
coupin = (int*)malloc ( (N+1)*sizeof(int) );//存储优惠券
goods = (int*)malloc ( (M+1)*sizeof(int) );//存储商品
int *coupin_f, *goods_f
coupin_f = (int*)malloc ( (c_f+1)*sizeof(int) ); //存储值为负的优惠券
goods_f = (int*)malloc ( (g_f+1)*sizeof(int) ); //存储值为负的商品
算法设计思想
1.设置循环在文件中读取优惠券和商品信息,并将其存储到对应数组里
2.统计值为正和值为负的优惠券和商品数量
3.再对数组进行从大到小的排序
4.排序完后遍历数组,将值为负的值按顺序付给 coupin_f和goods_f数组;
5.最后设置循环,值为正的优惠券和商品数组从头到尾依次相乘并相加;值为负的优惠券和商品数组从尾到头依次相乘并相加;两个结果最终相加得最优解;
测试数据和结果
输入
4 1 2 4 -1
4 7 6 -2 -3
输出 43
输入:
4 3 2 6 1
3 2 6 3
输出:49
算法时间复杂度
void creat_f ( int a[], int b[], int x, int y )//创建数组
时间复杂度:O(n)
void Qsort(int a[] , int low , int high , int n ) //快速排序 ,从大到小
时间复杂度:O(n*logn)
全部代码如下:
#include <iostream>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
using namespace std;
//快速排序 ,从大到小
int Partition ( int a[] , int low , int high , int n )
{
a[0]=a[low];
int pivotkey = a[low];
while ( low<high )
{
while ( low<high && a[high] <= pivotkey )
high--;
a[low] = a[high];
while ( low<high && a[low] >= pivotkey )
low++;
a[high] = a[low];
}
a[low] = a[0];
return low;
}
void Qsort(int a[] , int low , int high , int n )
{
if ( low<high)
{
int pivotloc=Partition ( a , low, high , n );
Qsort( a, low, pivotloc-1, n );
Qsort( a, pivotloc+1, high, n );
}
}
//创建值为负的数组
void creat_f ( int a[], int b[], int x, int y )
{
int i=0, j;
for ( i=x+1, j=1; i<=x+y; i++, j++ )
{
b[j] = a[i];
}
}
int main()
{
int N, M, i, j, money=0;
cout<< "优惠券:" ;
cin >> N;
int *coupin, *goods;
coupin = (int*)malloc ( (N+1)*sizeof(int) );//存储优惠券
int c_z = 0, c_f = 0;
int g_z = 0, g_f = 0 ;
for ( i=1; i<=N ; i++)
{
cin >> coupin[i];
if ( coupin[i]>0 )//0不存储
c_z++;//为正数的优惠券数量
else if ( coupin[i]<0 )
c_f++;//为负数的优惠券数量
}
cout<< "商品:" ;
cin >> M;
goods = (int*)malloc ( (M+1)*sizeof(int) );//存储商品
for ( i=1; i<=M; i++ )
{
cin >> goods[i];
if ( goods[i]>0 )//0不存储
g_z++;//价格为正数的商品数量
else if ( goods[i]<0 )
g_f++;//价格为负数的商品数量
}
int *coupin_f;//存储值为负的优惠券
int *goods_f;//存储值为负的商品
coupin_f = (int*)malloc ( (c_f+1)*sizeof(int) );
goods_f = (int*)malloc ( (g_f+1)*sizeof(int) );
Qsort ( coupin , 1, N, N );
Qsort( goods, 1, M, M );
creat_f( coupin, coupin_f, c_z, c_f );//为存储负数的数组赋值
creat_f( goods, goods_f, g_z, g_f );
for( i=1; i<=c_z&&i<=g_z; i++ )//值为正的从头到尾相乘
money += coupin[i]* goods[i];
for( i=c_f, j= g_f; i>0&&j>0; i--, j-- )//值为负的从尾到头相乘
money += coupin_f[i]* goods_f[j];
cout<<money;
return 0;
}