(Cf1141C). Polycarp Restores Permutation

(Cf1141C). Polycarp Restores Permutation

An array of integers ?1,?2,…,??p1,p2,…,pn is called a permutation if it contains each number from 11 to ?n exactly once. For example, the following arrays are permutations: [3,1,2][3,1,2], [1][1], [1,2,3,4,5][1,2,3,4,5] and [4,3,1,2][4,3,1,2]. The following arrays are not permutations: [2][2], [1,1][1,1], [2,3,4][2,3,4].

Polycarp invented a really cool permutation ?1,?2,…,??p1,p2,…,pn of length ?n. It is very disappointing, but he forgot this permutation. He only remembers the array ?1,?2,…,??−1q1,q2,…,qn−1 of length ?−1n−1, where ??=??+1−??qi=pi+1−pi.

Given ?n and ?=?1,?2,…,??−1q=q1,q2,…,qn−1, help Polycarp restore the invented permutation.

Input

The first line contains the integer ?n (2≤?≤2⋅1052≤n≤2⋅105) — the length of the permutation to restore. The second line contains ?−1n−1 integers ?1,?2,…,??−1q1,q2,…,qn−1 (−?<??<?−n<qi<n).

Output

Print the integer -1 if there is no such permutation of length ?n which corresponds to the given array ?q. Otherwise, if it exists, print ?1,?2,…,??p1,p2,…,pn. Print any such permutation if there are many of them.

Examples

input

3
-2 1

output

3 1 2 

input

5
1 1 1 1

output

1 2 3 4 5 

input

4
-1 2 2

output

-1

 

题意:

给定了a字符串,存的是 P(i+1) - Pi 的差值

例如P数组为  3 1 2  ,那么a数组为 -2 1

已知a数组,得到一个确定的P数组

 

思路:

类似为构造方法,先另第一个P[0] 为1,根据a数组依次求出每一位的数字是多少

然后找出一个最小值(minn),如果最小值小于等于0,那么说明这一种另第一个为1的方法不合法

就加上 ( -minn + 1),使这个最小值变成 1 ,然后每个数字都加上(-minn+1),类似于平移的思想

 

判断每一位数字是否满足   在1-n范围内,并且只出现一次,如果都满足就输出这个数列

如果不满足输出 -1

注意要用 long long



我哇了15次,说一下我的思路

我是类似于构造的方法,每次都加1,判断这一次合不合法,如果合法直接break,如果不合法就在继续进行,真的加到n

但这种方法会T,所以就有了下面这个图片,放在这督促我一下

 

 

 

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
typedef long long LL;
using namespace std;
#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f

const LL MAX = 2e5+5;
LL a[MAX];
LL dp[MAX];
LL vis[MAX];

int main()
{
    LL n;
    cin>>n;

    for(LL i=0;i<n-1;i++)
        cin>>a[i];

    memset(vis,0);

    dp[0]=1;
    LL cnt=1,flag=0;

    LL minn=INF;

    for(LL i=0;i<n-1;i++){
        dp[cnt]=dp[cnt-1]+a[i];
        if(dp[cnt]<minn)
            minn=dp[cnt];
        cnt++;
    }

    //cout<<minn<<"**"<<endl;

    if(minn<=0){
        minn=-minn;
        minn+=1;
        for(LL i=0;i<=n;i++)
            dp[i]+=minn;
    }


    for(int i=0;i<n;i++)
    {
        if(dp[i]>=1&&dp[i]<=n&&vis[dp[i]]==0)
            vis[dp[i]]=1;
        else{
            flag=1;
            break;
        }
    }



    if(flag==1){
        cout<<"-1"<<endl;
        return 0;
    }

    for(LL i=0;i<n;i++){
        if(i==0)
            cout<<dp[i];
        else
            cout<<' '<<dp[i];
    }

    cout<<endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值