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