pat 1044 Shopping in Mars

火星人购物使用钻石链,每颗钻石都有一定的价值。付款是,要求从钻石链上找到所有刚好能匹配到商品价值的连续的钻石子链,如果没有, 则找到超过商品价值的最小的钻石子链。

比如钻石链为3 2 1 5 4 6 8 7,商品价值为15,则候选的方案有:第 4 到第 6 颗的子链5 4 6,第 7 到第 8 颗:8 7

输入为一个钻石链以及商品的价值,要求找到所有满足条件的分割方案,按起始点从小到大排序输出。

   解题思路:比较简单, 从起始点每个点开始依次向后遍历相加,直到相加值大于等于设定商品价值。若等于直接输出,若大于则将此次相加的起始位置和结束位置予以存储,并且保存此次值;当遍历完整后还是没有匹配方案,计算所有大于商品价值中的最小值

予以输出该最小值对应起始结束位置。

  但由于该题对于时间要求比较严,所以正常的提交还是有三个用例超时;

 优化思路:整体算法的O(N~2)很难进行优化,对于一些细节优化:

1,当这次相加到j点是等于设定值时,那么下次换下个点作为起始点时,就可以跳过中间步骤,直接从j+1点开始累加,注意记录上次累加的值为sum = sum - diamond[i],从该值进行累加;

2,当这次相加值大于设定值时,可以比较起始点和结束点大小,若起始点大于结束点,方法可以参照第一个;

3,当从某个点开始遍历到最后都没能超过设定值时,此后的所有点都可以忽略作为起始点;

 按照以上方法进行提交后,发现还是 有个测试用例超时,想了半天没有啥方法,想起scanf要比cin的输入方式效率要高,就尝试换了输入方式,结果果然时间大大减少,原来通过的用例用时要40ms,现在都变成了10ms,竟然变化这么大

  1 //
  2 //  1044.cpp
  3 //  pat
  4 //
  5 //  Created by apple on 14-2-17.
  6 //  Copyright (c) 2014年 apple. All rights reserved.
  7 //
  8 #include <iostream>
  9 #include <vector>
 10 #include <stdio.h>
 11 using namespace std;
 12 #define MAX 100001
 13 int diamond_value[MAX] = {0};
 14 int min_value[MAX] = {0};
 15 struct Serial_over
 16 {
 17     int value;
 18     int start;
 19     int end;
 20 };
 21 
 22 vector <Serial_over> over_list;
 23 
 24 
 25 int main()
 26 {
 27     int num_diamond;
 28     int value;
 29     int i,j;
 30     int sum = 0;
 31     int success_flag = 0;
 32     int count_over;
 33     int flag,tmp;
 34     int start;
 35     int min_value = 100000001;
 36     flag = 0;
 37     cin>>num_diamond>>value;
 38     
 39     for (i = 0; i < num_diamond; i++)
 40     {
 41         scanf("%d",&diamond_value[i]);
 42     }
 43     
 44     for(i = 0; i < num_diamond; i++)
 45     {
 46         if(flag == 1)
 47         {
 48             start = tmp+1;
 49             sum = sum - diamond_value[i-1];
 50             flag = 0;
 51         }
 52         else
 53         {
 54             start = i;
 55             sum = 0;
 56         }
 57         
 58         for(j = start;j < num_diamond; j++)
 59         {
 60             sum+=diamond_value[j];
 61             if (sum >= value)
 62             {
 63                 break;
 64             }
 65         }
 66         
 67         if(j == num_diamond)
 68         {
 69             break;
 70         }
 71         
 72         if (sum == value)
 73         {
 74             flag = 1;
 75             tmp = j;
 76             printf("%d-%d
",i+1,j+1);
 77             success_flag = 1;
 78         }
 79         else if(sum > value)
 80         {
 81             if (sum < min_value) {
 82                 min_value = sum;
 83             }
 84             if (diamond_value[j] < diamond_value[i]) {
 85                 flag = 1;
 86                 tmp = j;
 87             }
 88             struct Serial_over over_data;
 89             over_data.value = sum;
 90             over_data.start = i + 1;
 91             over_data.end = j+1;
 92             over_list.push_back(over_data);
 93         }
 94         
 95     }
 96     
 97     if (!success_flag)
 98     {
 99         for(i = 0; i < over_list.size(); i++)
100         {
101             if (over_list[i].value == min_value)
102             {
103                 printf("%d-%d
",over_list[i].start,over_list[i].end);
104             }
105             
106         }
107     }
108     
109     
110     return 0;
111 }
原文地址:https://www.cnblogs.com/likelight/p/PAT.html