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

PAT (Advanced) 1044. Shopping in Mars (25)

2018-03-05 11:47 579 查看
原题:1044. Shopping in Mars (25)

解题思路:
要求区间和,首先想办法把区间和保存下来,sum[i]表示下标从0到i的钻石和。这样sum[j]-sum[i]+val[i]就是区间i到j的和了。
再就是连续区间和问题,很容易想到一个窗口的思想,直接枚举窗口会超时,所以必须利用前面计算出的区间和的大小来判断窗口的变化,详情见代码。

代码如下:#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100000 + 5;
const int INF = 0x3fffffff;
int val[maxn];
int sum[maxn];
int n, toPay;

int main()
{
while(scanf("%d%d", &n, &toPay) == 2)
{
for(int i = 0; i < n; i++)
{
scanf("%d", &val[i]);
if(i) sum[i] = sum[i-1]+val[i];
else sum[i] = val[i];
}
int l = 0, r = 0, minval = INF;
while(l < n)
{
if(sum[r] - sum[l] + val[l] < toPay && r < n) r++; //区间和太小,右边加一个数
else if(sum[r] - sum[l] + val[l] > toPay) //太大,左边减一个数,并且记录此时大于要求的最小值
{
minval = min(minval, sum[r] - sum[l] + val[l]);
l++;
}
else if(sum[r] - sum[l] + val[l] == toPay) //相等直接打印,并更新最小值
{
minval = toPay;
printf("%d-%d\n", l+1, r+1);
l++;r++;
}
else break;
}
if(minval > toPay) //无解的情况
{
int l = 0, r = 0;
while(l < n)
{
if(sum[r] - sum[l] + val[l] < minval && r < n) r++;
else if(sum[r] - sum[l] + val[l] > minval) l++;
else if(sum[r] - sum[l] + val[l] == minval)
{
printf("%d-%d\n", l+1, r+1);
l++;r++;
}
else break;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: