计蒜客暑假集训第一阶段第五场 d题

Do you like number pyramids? Given a number sequence that represents the base, you are usually supposed to build the rest of the "pyramid" bottom-up: For each pair of adjacent numbers, you would compute their sum and write it down above them. For example, given the base sequence [1, 2, 3][1,2,3], the sequence directly above it would be [3, 5][3,5], and the top of the pyramid would be [8][8]:

However, I am not interested in completing the pyramid – instead, I would much rather go underground. Thus, for a sequence of nn non-negative integers, I will write down a sequence of n + 1n+1 non-negative integers below it such that each number in the original sequence is the sum of the two numbers I put below it. However, there may be several possible sequences or perhaps even none at all satisfying this condition. So, could you please tell me how many sequences there are for me to choose from?

Input Format

The input consists of:

  • one line with the integer nn (1 \le n \le 10^6)(1≤n≤106), the length of the base sequence.
  • one line with n integers a_1, \cdots , a_na1​,⋯,an​ (0 \le ai \le 10^8(0≤ai≤108 for each i)i), forming the base sequence.

Output Format

Output a single integer, the number of non-negative integer sequences that would have the input sequence as the next level in a number pyramid.

样例输入1

6
12 5 7 7 8 4

样例输出1

2

样例输入2

3
10 1000 100

样例输出2

0

题目大意:

给定一串数字,共有n个数字,让你找到一串数字,这串数字共有n+1个数字,满足任何相邻的两个数的和等于这两个数上面相对应的数,相当于杨辉三角,让你求满足这种条件的数字串的个数。

思路:

超时思路:

深搜,对于每个位置都枚举一遍,找出满足条件的数字串。

正确思路:

对于一串数字,我们假设我们找到的数字串的第一个数字为x,依次往后推,求出所有的数字。

对于每个求出的数字,我们必须确保该数字是正数(题目要求),然后求出满足所有数字是正数的x的取值范围,此时这个范围内数字的个数就是满足条件的数字串的个数。

通过观察发现,对于有些数字,当x增大时,该数字是减小的(下图中用红点标出的数字),对于有些数字,当x增大时,该数字是增大的。

通过这个条件,我们可以把数字划分为两类:

第一类:当x增大时,该数字是减小的。

第二类:当x增大时,该数字是增大的。

经过计算,上面的例子x的范围是【7,12】。接下来讲怎样的得到的这个范围。

通过观察上图的第一类数字(用红点标记的数字),如果要保证数字是正数,x的最大值只能是12。这个地方只能确定x的最大值。

然后观察第二类数字(没用红点标记的数字),如果要保证数字是正数,x的最小值只能是7。这个地方只能确定x的最小值。

所以x的范围是【7,12】。最后的结果就是12-7+1=6。

代码:

​
#include<bits/stdc++.h>
#define MAXN 1000010
typedef long long ll;
using namespace std;
int n;
ll root[MAXN];
ll add[MAXN];
int i1=1;
ll minu[MAXN];
int i2=0;
ll addmin=INT_MAX,minumin=INT_MAX;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>root[i];
    ll z=0,l=0;
    add[0]=0;
    for(int i=1;i<=n;i++)
    {
        if(i%2==1)
        {
            z=root[i]-l;
            minu[i2++]=z;
        }
        else if(i%2==0)
        {
            l=root[i]-z;
            add[i1++]=l;
        }
    }
    for(int i=0;i<i1;i++)
        addmin=min(addmin,add[i]);
    for(int i=0;i<i2;i++)
        minumin=min(minumin,minu[i]);
    addmin=-addmin;
    if(addmin>minumin)
        cout<<'0';
    else
        cout<<minumin-addmin+1;
}

​

代码有很多细节,这里不一一讲了,自己找个例子模拟一下代码,就知道了

猜你喜欢

转载自blog.csdn.net/qq_40938077/article/details/81281082
今日推荐