当前位置:   article > 正文

Day 9~PAT B1020,PAT B1023,区间贪心_每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 n 表示

每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 n 表示

简单贪心:总是考虑当前状态下的局部最优,以求全局最优

输入:每个输入包含一个测试用例。每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数以及不超过500(以万吨为单位)

的正整数D表示市场最大需求量;随后一行给出N个正数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正数表示每种月饼的总售价

输出:对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后两位。

  1. #include<stdio.h>
  2. #include<algorithm>
  3. using namespace std;
  4. /*
  5. 简单贪心:总是考虑当前状态下的局部最优,以求全局最优
  6. 输入:每个输入包含一个测试用例。每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数以及不超过500(以万吨为单位)
  7. 的正整数D表示市场最大需求量;随后一行给出N个正数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正数表示每种月饼的总售价
  8. 输出:对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后两位。
  9. */
  10. struct moonCake{
  11. double inventory; //库存量
  12. double totalPrice; //总售价
  13. double averagePrice; //均价
  14. }mCake[1010];
  15. bool cmp(moonCake a,moonCake b){
  16. return a.averagePrice>b.averagePrice;
  17. }
  18. int main(){
  19. int n;
  20. double d; //n表示月饼的种类数,d表示当前的的市场需求量
  21. printf("请输入n(n<=1000),d(d<=500):");
  22. scanf("%d %lf",&n,&d);
  23. for(int i = 0;i<n;i++){
  24. scanf("%lf",&mCake[i].inventory);
  25. }
  26. for(int i = 0;i<n;i++){
  27. scanf("%lf",&mCake[i].totalPrice);
  28. mCake[i].averagePrice = mCake[i].totalPrice / mCake[i].inventory;
  29. }
  30. sort(mCake,mCake+n,cmp); //将月饼按照从均价从高到低排序
  31. double revenue = 0; //总收益
  32. for(int i = 0;i<n;i++){
  33. if(d >= mCake[i].inventory){
  34. d = d - mCake[i].inventory;
  35. revenue+=mCake[i].totalPrice;
  36. }else{ //剩余的市场需求量小于当前月饼的库存量,则满足市场需求量即可
  37. revenue += d * mCake[i].averagePrice;
  38. break;
  39. }
  40. }
  41. printf("%.2f\n",revenue);
  42. return 0;
  43. }

给定数字0~9若干个,可以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小

例如给定两个0,两个1,三个5,一个8,最后得到的最小的数就是10015558

输入格式:每个输入包含一个用例,每个测试用例在一行中给出十个非负整数,顺序表示所拥有数字0,数字1,....数字9的个数

十个数字的总个数不超过50,且至少拥有一个非0数字

输出:在一行中输出所能够组成的最小的数

  1. #include<stdio.h>
  2. /*
  3. 给定数字0~9若干个,可以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小
  4. 例如给定两个0,两个1,三个5,一个8,最后得到的最小的数就是10015558
  5. 输入格式:每个输入包含一个用例,每个测试用例在一行中给出十个非负整数,顺序表示所拥有数字0,数字1,....数字9的个数
  6. 十个数字的总个数不超过50,且至少拥有一个非0数字
  7. 输出:在一行中输出所能够组成的最小的数
  8. */
  9. int num[2][10]; //第一行表示0~9的数字,第二行表示每个数字的个数
  10. int main(){
  11. while(1){
  12. int count = 0;
  13. printf("请输入10个数字:");
  14. for(int i = 0;i<10;i++){
  15. scanf("%d",&num[1][i]);
  16. count += num[1][i];
  17. }
  18. if(count<=50 && num[1][0] != 50){ //十个数字的总个数不超过50,且至少拥有一个非0数字
  19. break;
  20. }else{
  21. printf("输入格式不规范!\n");
  22. }
  23. }
  24. //组最小的数,肯定是把本组数字中最小的数放在高位(保证高位不为0),把较大的数放在低位
  25. int Minimal[55];
  26. int flag = 0;
  27. //先放高位
  28. for(int i = 1;i<10;i++){
  29. if(num[1][i] != 0){
  30. Minimal[flag++] = i;
  31. num[1][i]--;
  32. break; //找到最高位放什么数字之后,跳出循环
  33. }
  34. }
  35. bool zeroExits = false; //true:存在若干个0,false:不存在0
  36. if(num[1][0] != 0){
  37. zeroExits = true;
  38. }
  39. if(zeroExits == true){
  40. for(int i = 1;i<=num[1][0];i++){
  41. Minimal[flag++] = 0;
  42. }
  43. for(int i = 1;i<10;i++){
  44. if(num[1][i] != 0){ //这个数字没有被用尽,因为是从小到大的顺序,所以放到高位
  45. for(int j = 1;j<=num[1][i];j++){
  46. Minimal[flag++] = i;
  47. }
  48. }
  49. }
  50. }else{ //不存在0
  51. for(int i = 1;i<10;i++){
  52. if(num[1][i] != 0){ //这个数字没有被用尽,因为是从小到大的顺序,所以放到高位
  53. for(int j = 1;j<=num[1][i];j++){
  54. Minimal[flag++] = i;
  55. }
  56. }
  57. }
  58. }
  59. //输出
  60. for(int i = 0;i<flag;i++){
  61. printf("%d",Minimal[i]);
  62. }
  63. printf("\n");
  64. return 0;
  65. }

给出N个开区间(x,y),从中选择尽可能多的开区间,使得这些开区间两两没有交集

  1. #include<stdio.h>
  2. #include<algorithm>
  3. using namespace std;
  4. /*
  5. 给出N个开区间(x,y),从中选择尽可能多的开区间,使得这些开区间两两没有交集
  6. */
  7. const int maxn = 110;
  8. struct Interval{
  9. int x;
  10. int y;
  11. }I[maxn];
  12. bool cmp(Interval a,Interval b){
  13. if(a.x == b.x){
  14. return a.y<b.y;
  15. }else{
  16. return a.x>b.x;
  17. }
  18. }
  19. int main(){
  20. int n; //代表区间的个数
  21. while (scanf("%d",&n),n != 0)
  22. {
  23. /* code */
  24. for(int i = 0;i<n;i++){
  25. scanf("%d%d",&I[i].x,&I[i].y); //输入每个区间的左右端点值
  26. }
  27. sort(I,I+n,cmp); //按照横坐标从大到小排列,横坐标相同时按纵坐标从小到大排列
  28. //ans记录当前不相交子区间的个数,lastX记录上一个被选中区间的左端点
  29. int ans = 1,lastX = I[0].x;
  30. for(int i = 1;i<n;i++){
  31. if(I[i].y <= lastX){ //如果该区间右端点在lastX左边
  32. ans++; //不相交区间个数加1
  33. lastX = I[i].x; //以I[i]作为新选中的区间
  34. }
  35. }
  36. printf("%d\n",ans);
  37. }
  38. return 0;
  39. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/93727
推荐阅读
相关标签
  

闽ICP备14008679号