codeforces-1141C好坑的思维题

C. Polycarp Restores Permutation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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

.

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

.

Given n
and q=q1,q2,…,qn−1

, help Polycarp restore the invented permutation.
Input

The first line contains the integer n
(2≤n≤2⋅105) — the length of the permutation to restore. The second line contains n−1 integers q1,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 p1,p2,…,pn

. Print any such permutation if there are many of them.
Examples
Input
Copy

3
-2 1

Output
Copy

3 1 2

Input
Copy

5
1 1 1 1

Output
Copy

1 2 3 4 5

Input
Copy

4
-1 2 2

Output
Copy

-1
题意:有n个数,后面给出了n-1个数字,表示的是第n+1个数-第n个数的值
然后叫我们输出这n个数,这n个数是由前n组合成的,每个数都是不同的而且必须从1开始,不能跳过一些数比如1 2 4 5是不行的,因为少了3,1 1也是不行的因为重复了,0 2 4也是不行的因为最小是从1开始
思路:我们可以设第一个数为x,然后可以推出后面的数和第一个数的关系
比如第一个样例num[1]=x num[2]=x-2 num[3]=x-1
这三个数的和 == 3x-3 也就等于从1到3和,也就是前N项和
然后我们解方程n*(n+1)/2 = 3x-3 可以算出第一个数x,这样我们就可以推出之后的数。推出第一个数之后我们还要判断有没有找对,比如第三组样例
10 = 4x+2 得出x==2 但这是错的,原因这样算出来数列是 2 0 3 6
所以我们之后还要判断找出x后的数列是不是符合的,这个bool数组就可以了
坑点:范围,绝对不能用int 不能用int 不能用int !!!要用long long (我什么都不知道5555555555)还有一个坑点代码说了
AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2e5+10;
long long int num[maxn],sum[maxn];	//不要忘了
int main()	
{
	long long int n,m,k;		//long long 
	long long int ans;
	cin>>n;
	m=0;k=0;
	memset(num,0,sizeof(num));
	for (int i=1;i<n;i++)
		{
			scanf("%lld",&num[i]);
			num[i]=num[i-1]+num[i];
			m=m+num[i];
		}
	if (n%2==0) ans=(n/2)*(n+1);   //看一下n的范围就知道这里要注意
	else ans=((n+1)/2)*n;
//	cout<<ans<<endl;
	if ((ans-m)%n==0) k=(ans-m)/n;
	else k=-1;
//	cout<<k<<endl;
	for (int i=0;i<n;i++)
		{
			if (k+num[i]<=0||k+num[i]>maxn-10)	//这里是找有没有重复和缺少的
				break;		//注意范围,大于n最大也是不需要考虑的,因为数列最大不能超过n
			sum[k+num[i]]=1;
	//		cout<<k+num[i]<<"--"<<k<<endl;
		}
	sort(sum+1,sum+n+1);		//数组有0说明有缺少
	if (sum[1]==0)
		k=-1;
	if (k<=0) cout<<-1;
	else 
	for (int i=0;i<n;i++)
		if (i==0) cout<<k;
		else cout<<" "<<k+num[i];
	cout<<endl;
	return 0;
}

略坑略坑

发布了46 篇原创文章 · 获赞 2 · 访问量 3207

猜你喜欢

转载自blog.csdn.net/z1164754004z/article/details/88725139