PTA数据结构与算法题目集(中文) 7-39魔法优惠券 (25 分)
7-39 魔法优惠券 (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, 1]之间,所有的数据大小不超过230,数字间以空格分隔。
输出格式:
输出可以得到的最大回报。
输入样例:
4 1 2 4 -1
4 7 6 -2 -3
输出样例:
43
题目分析:用优先队列来每次找出最好的情况,看了大佬的做法,其实只需要排序就好了,每次找出符号相同的最好情况 但这题我最后一个测试题无法通过
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<string.h> 4 #include<malloc.h> 5 #define INIFITY -65535 6 typedef struct HeapStruct* H; 7 struct HeapStruct 8 { 9 int Heap[1000010]; 10 int Size; 11 }MaxHeap1,MaxHeap2; 12 13 int Delete(H MaxHeap) 14 { 15 int Max = MaxHeap->Heap[1]; 16 int Tmp = MaxHeap->Heap[MaxHeap->Size--]; 17 int Parent, Child; 18 for (Parent = 1; Parent * 2 <= MaxHeap->Size; Parent = Child) 19 { 20 Child = Parent * 2; 21 if (Child != MaxHeap->Size && MaxHeap->Heap[Child] < MaxHeap->Heap[Child + 1]) 22 Child++; 23 if (Tmp >= MaxHeap->Heap[Child])break; 24 else 25 MaxHeap->Heap[Parent] = MaxHeap->Heap[Child]; 26 } 27 MaxHeap->Heap[Parent] = Tmp; 28 return Max; 29 } 30 int DeleteM(H MinHeap) 31 { 32 int Min = MinHeap->Heap[1]; 33 int Tmp = MinHeap->Heap[MinHeap->Size--]; 34 int Parent, Child; 35 for (Parent = 1; Parent * 2 <= MinHeap->Size; Parent = Child) 36 { 37 Child = Parent * 2; 38 if (Child != MinHeap->Size && MinHeap->Heap[Child]>MinHeap->Heap[Child + 1]) 39 Child++; 40 if (Tmp <= MinHeap->Heap[Child])break; 41 else 42 MinHeap->Heap[Parent] = MinHeap->Heap[Child]; 43 } 44 MinHeap->Heap[Parent] = Tmp; 45 return Min; 46 } 47 48 void PrecDown(H MaxHeap, int i) 49 { 50 int Parent, Child; 51 int Tmp = MaxHeap->Heap[i]; 52 for (Parent = i; Parent * 2 <= MaxHeap->Size; Parent = Child) 53 { 54 Child = Parent * 2; 55 if (Child != MaxHeap->Size && MaxHeap->Heap[Child] < MaxHeap->Heap[Child + 1]) 56 Child++; 57 if (Tmp >= MaxHeap->Heap[Child])break; 58 else 59 MaxHeap->Heap[Parent] = MaxHeap->Heap[Child]; 60 } 61 MaxHeap->Heap[Parent] = Tmp; 62 } 63 void BuildHeap(H MaxHeap) 64 { 65 for (int i = MaxHeap->Size / 2; i; i /= 2) 66 PrecDown(MaxHeap, i); 67 } 68 void PrecDownM(H MinHeap, int i) 69 { 70 int Parent, Child; 71 int Tmp = MinHeap->Heap[i]; 72 for (Parent = i; Parent * 2 <= MinHeap->Size; Parent = Child) 73 { 74 Child = Parent * 2; 75 if (Child != MinHeap->Size && MinHeap->Heap[Child] > MinHeap->Heap[Child + 1]) 76 Child++; 77 if (Tmp <= MinHeap->Heap[Child])break; 78 else 79 MinHeap->Heap[Parent] = MinHeap->Heap[Child]; 80 } 81 MinHeap->Heap[Parent] = Tmp; 82 } 83 void BuildHeapM(H MinHeap) 84 { 85 for (int i = MinHeap->Size / 2; i; i /= 2) 86 PrecDownM(MinHeap, i); 87 } 88 int main() 89 { 90 MaxHeap1.Heap[0] = MaxHeap2.Heap[0] = INIFITY; 91 int N, M; 92 int num,sum; 93 scanf("%d", &N); 94 MaxHeap1.Size = N; 95 for (int i = 1; i <=MaxHeap1.Size; i++) 96 { 97 scanf("%d", &num); 98 MaxHeap1.Heap[i] = num; 99 } 100 scanf("%d", &M); 101 MaxHeap2.Size = M; 102 for (int i = 1; i <=MaxHeap2.Size; i++) 103 { 104 scanf("%d", &num); 105 MaxHeap2.Heap[i] = num; 106 } 107 BuildHeap(&MaxHeap1); 108 BuildHeap(&MaxHeap2); 109 sum = 0; 110 int num1, num2; 111 int t = N > M ? M : N; 112 while (MaxHeap1.Size!=0&&MaxHeap2.Size!=0) 113 { 114 if (MaxHeap1.Heap[1] > 0 && MaxHeap2.Heap[1] > 0) 115 { 116 num1 = Delete(&MaxHeap1); 117 num2 = Delete(&MaxHeap2); 118 sum += num1 * num2; 119 } 120 else 121 break; 122 } 123 BuildHeapM(&MaxHeap1); 124 BuildHeapM(&MaxHeap2); 125 while (MaxHeap1.Size!=0&&MaxHeap2.Size!=0) 126 { 127 if (MaxHeap1.Heap[1] < 0 && MaxHeap2.Heap[1] < 0) 128 { 129 num1 = DeleteM(&MaxHeap1); 130 num2 = DeleteM(&MaxHeap2); 131 sum += num1 * num2; 132 } 133 else 134 break; 135 } 136 printf("%d", sum); 137 }