1. 程式人生 > >51Nod 1094 和為k的連續區間 字首和+map應用

51Nod 1094 和為k的連續區間 字首和+map應用

一整數數列a1, a2, ... , an(有正有負),以及另一個整數k,求一個區間[i, j],(1 <= i <= j <= n),使得a[i] + ... + a[j] = k。

收起

輸入

第1行:2個數N,K。N為數列的長度。K為需要求的和。(2 <= N <= 10000,-10^9 <= K <= 10^9)
第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)。

輸出

如果沒有這樣的序列輸出No Solution。
輸出2個數i, j,分別是區間的起始和結束位置。如果存在多個,輸出i最小的。如果i相等,輸出j最小的。

輸入樣例

6 10
1
2
3
4
5
6

輸出樣例

1 4

 先求出1-i的字首和,然後用map儲存起來。

因為 sum[r]-sum[l]=k;

所以之後求是否在map中存在k+sum[i]。若存在則按從小到大查詢sum[j]-s[i]==k

程式碼如下:
 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
const int maxn=10005;
typedef long long ll;
ll a[maxn],sum[maxn];
ll k;
int n;
map<ll,ll>ma;
int main()
{
    memset (sum,0,sizeof(sum));
    scanf("%d%lld",&n,&k);
    for (int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
        ma[sum[i]]=1;
    }
    int flag=0;
    for (int i=0;i<=n;i++)
    {
        if(ma[sum[i]+k])
        {
            for (int j=i;j<=n;j++)
            {
                if(sum[j]-sum[i]==k)
                {
                    flag=1;
                    printf("%d %d\n",i+1,j);
                    return 0;
                }
            }
        }
    }
    if(!flag)
    {
        printf("No Solution\n");
    }
    return 0;
}