zoukankan      html  css  js  c++  java
  • 1044 Shopping in Mars (25 分)

    题意

    给出一个数字序列与一个数S,在数字序列中求出所有和值为S的连续子序列(区间下标左端点小的先输出,左端点相同时右端点小的先输出)。若没有这样的序列,求出和值恰好大于S的子序列(即在所有和值大于S的子序列中和值最接近S)。假设序列下标从1开始。

    思路
    令Sum[i]表示A[1]到A[j]的和值,即令Sum[i] =a[1]+ a[2] +...+ a[i]。要注意序列都是正值,因此Sum[j]一定是严格单调递增的,即有Sum[1] < Sum[2] <...< Sum[n]成立(为了下面计算方面,初始化Sum[0] =0)。这样做的好处在于,如果要求连续子序列A[j到A[i]的和值,只需要计算Sum[j] - Sum[i-1]即可。

    既然Sum数组严格单调递增,那就可以用二分法来做这道题。假设需要在序列A[1] ~ A[n]中寻找和值为S的连续子序列,就可以枚举左端点i(1≤i≤n),然后在Sum数组的[i, n]范围内查找值为Sum[i- 1]+S的元素(由Sum[j]-Sum[i-1]=S推得)是否存在:如果存在,则把对应的下标作为右端点j;如果不存在,找到第一个使和值超过S的右端点j。可以直接按照lower_bound 函数或者upper_bound函数的写法来解决这个问题。但是要注意,在使用upper_bound时求得的位置并不一定是恰好是右端点的位置(可能需要减1)。

    const int N=1e5+10;
    int a[N];
    int sum[N];
    int n,m;
    
    int main()
    {
        cin>>n>>m;
    
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
    
        bool ok=false;
        int l=1,r=n;
        vector<PII> res;
        for(int i=1;i<=n;i++)
        {
            int j=lower_bound(sum+i,sum+n+1,m+sum[i-1])-sum;
            if(j > n) sum[j]=INF;
    
            if(sum[j]-sum[i-1] == m)
            {
                ok=true;
                cout<<i<<'-'<<j<<endl;
            }
    
            if(sum[j]-sum[i-1] < sum[r]-sum[l-1])
            {
                res.clear();
                l=i,r=j;
                res.pb({i,j});
            }
            else if(sum[j]-sum[i-1] == sum[r]-sum[l-1])
            {
                res.pb({i,j});
            }
        }
    
        if(!ok)
            for(int i=0;i<res.size();i++)
                cout<<res[i].fi<<'-'<<res[i].se<<endl;
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    PostMan 安装步骤详解
    使用MySQL,运行系统报错Authentication method 'caching_sha2_password' is not supported.
    jmeter安装和环境变量配置
    Svn项目迁移到Git及Visual Studio 中git使用
    SQLServer 2008以上误操作数据库恢复方法
    ABP入门系列之3——创建实体/Code First创建数据表
    ABP入门系列之2——ABP模板项目
    uni-app使用Canvas绘图
    uni-app中picker组件的一个坑
    Nginx用法详解
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14417820.html
Copyright © 2011-2022 走看看