您的位置:首页 > 运维架构

pat1044Shopping in Mars (25)

2015-10-13 16:33 267 查看
题意分析:

(1)给出一个整数序列,截取这个序列中的一段连续的子序列使得这个子序列的和等于给定的值,若不存在这样的序列,则找出序列的和大于给定值并且差值最小的。如有多个这样的序列,按照左边界的升序输出这些边界

(2)一种简单的方法是从第一个位置开始,依次计算从第1、2..开始的连续和到等于M或者第一次大于M,在从第二个位置开始依次类推,这样时间复杂度就是o(n^2),很遗憾,这样的方案会导致有些案例超时。我们可以这样考虑:既然是求从i到j的连续和这个地方的O(n)限制了算法的效率,有什么办法能够很快很直观地直接以O(1)的效率算出来呢?可以!若s[i]表示从0到i的连续和,那么从i到j之间的元素连续和就是s[j]-s[i-1],这样一开始输入元素的时候,我们便可将前面的和与当前元素的和加起来作为新元素的值。

可能坑点:

(1)不能使用暴力破解。

(2)依然不能使用C++的标准输入输出流。这里需要说一下:我个人觉得以输入输出流的效率作为算法是否通过测试的方式不可取。编程题应侧重于算法本身设计合不合理,而不应当在输入输出效率上设关卡。以这也是很多人做PAT算法题吐槽的地方,即使是各大IT公司在线笔试题也没有这种限制。所以PAT还是有很多需要完善的地方。

#include <iostream>
#include <vector>
#include <limits.h>
#include <stdio.h>
using namespace std;

struct position
{
int begin;
int end;
};
int main()
{
int N,M;
scanf("%d%d",&N,&M);
const int num=N;
int array[num];
int i=1;
int value;
array[0]=0;
while(i<=N)
{
scanf("%d",&value);
array[i]=array[i-1]+value;
i++;
}
int flag=0;
vector<position>vec;
int min_lost=INT_MAX;
position p;
int a=0,b=1;
while(b<=N)
{
int sum=array[b]-array[a];
if(sum==M)
{
printf("%d-%d\n",a+1,b);
flag=1;
a++;
b++;
}
else if(sum>M)
{
if(sum<min_lost)
{
vec.clear();
p.begin=a+1;
p.end=b;
vec.push_back(p);
min_lost=sum;
}
else if(sum==min_lost)
{
p.begin=a+1;
p.end=b;
vec.push_back(p);
}
a++;
}
else b++;
}
if(!flag)
{
for(int i=0;i<vec.size();i++)printf("%d-%d\n",vec[i].begin,vec[i].end);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: