Imprecise Computer - ( 思维 / 递推 )

题目描述

The Imprecise Computer (IC) is a computer with some structural issue that it can compare two integers correctly only when their difference is at least two. For example, IC can always correctly answer ‘4 is larger than 2’, but it can answer either ‘2 is larger than 3’ or ‘3 is larger than 2’ (in this case, IC arbitrarily chooses one of them). For two integers x and y, we say ‘x defeats y’ when IC answers ‘x is larger than y’.

Given a positive integer n, let Pn = {1, 2, … , n} be the set of positive integers from 1 to n. Then we run a double round-robin tournament on Pn using IC. The double-round-robin tournament is defined as follows:
1.The tournament is composed of two rounds (the 1st round and the 2nd round).
2.For each round, each element in Pn is compared to every other element in Pn.
Now for each element k in Pn, let ri(k) be the number of wins of k in the i-th round of the tournament. We also define the ‘difference sequence’ D = d1d2…dn where for each 1 ≤ k ≤ n, dk = |r1(k) − r2(k)|.

The following shows an example when n = 5.

Imprecise Computer - ( 思维 / 递推 )
In the example above, r1(1) = 0, r1(2) = 1, r1(3) = 3, r1(4) = 3, r1(5) = 3, and r2(1) = 1, r2(2) = 1, r2(3) = 1, r2(4) = 3,r2(5) = 4. Therefore, the difference sequence is D = 1 0 2 0 1 in this example.

Given a sequence of n nonnegative integers, write a program to decide whether the input sequence can be a difference sequence of Pn.

输入

Your program is to read from standard input. The input starts with a line containing an integer n, (3 ≤ n ≤ 1,000,000), where n is the size of Pn. In the following line, a sequence of n integers between 0 and n is given, where each element in the sequence is separated by a single space.

输出

Your program is to write to standard output. Print exactly one line. Print YES if the sequence can be the difference sequence of Pn, and print NO otherwise.

样例输入

【样例1】
5
1 0 2 0 1
【样例2】
5
1 1 2 1 0

样例输出

【样例1】
YES
【样例2】
NO

题意

集合 Pn = { 1,2,3 … n },两轮游戏 , 每轮游戏 ,集合中的数两两对决,r1 ( k ) 代表数字 k 在 第一轮 游戏中胜利的次数 , r2 ( k ) 代表数字 k 在 第二轮 游戏中胜利的次数 ,d ( k ) = | r1 ( k ) - r2 ( k ) | ;
对决的规则:
如果 | 数x - 数y | >= 2 , 那么两个数中大的数胜利;
如果 | 数x - 数y | == 1 ,那么有两种可能( x 胜利 或者 y 胜利 )
给你数字 n ,再给你一个 d ( i ) ( 1 <= i <= n ) 的序列,问这个序列是否合法

思路

对于 1 , 只受 2 的影响;
对于 i ( 2 <= i <= n - 1 ) 只受 i - 1 和 i + 1 的影响;
对于 n 只受 n - 1 的影响;
取变量 pre 为 i - 1 对 i 产生的影响:

如果第一轮与第二轮 i - 1 与 i 的大小关系不一样,那么 i - 1 将对 i 产生 1 的影响( 单看这两个,差值为 1 );
如果第一轮与第二轮 i - 1 与 i 的大小关系一样,那么 i - 1 将对 i 产生 0 的影响( 单看这两个,差值为 0 );

对于每个位置的数 d ( i ) = d ( i - 1 ) 的影响 + d ( i + 1 ) 的影响;
因此 d ( i + 1 ) 的影响 = d ( i ) - d ( i - 1 ) 的影响;
即:

如果当前位置的数 d ( i ) == pre ,说明只有 d ( i - 1 ) 对它起了影响,d ( i + 1 ) 对它的影响为 0 ,也就是 d ( i ) 对 d ( i + 1 ) 的影响为 0 ,所以更新 pre 取值 0 ;

如果当前位置的数 d ( i ) == pre + 1 ,说明 d ( i - 1 ) 和 d ( i + 1 ) 都对它起了影响,d ( i + 1 ) 对它的影响为 1 ,也就是 d ( i ) 对 d ( i + 1 ) 的影响为 1 ,所以更新 pre 取值 1 ;
(例:1,2,3,第一轮:1 > 2 , 2 < 3 , 第二轮:1 < 2 , 2 > 3 , d 序列为,1,2,1)( 3 对 2 产生正影响 )

如果当前位置的数 d ( i ) == pre - 1 ,说明 d ( i - 1 ) 和 d ( i + 1 ) 都对它起了影响,d ( i + 1 ) 对它的影响为 1 ,也就是 d ( i ) 对 d ( i + 1 ) 的影响为 1 ,所以更新 pre 取值 1 ;
(例:1,2,3,第一轮:1 > 2 , 2 > 3 , 第二轮:1 < 2 , 2 < 3 , d 序列为,1,0,1)( 3 对 2 产生负影响 )

通过递推更新 pre 的值,来确定序列 d 的合法性

代码

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
int n,a[maxn],flag,pre;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n; 
    for(int i=1;i<=n;i++)    
        cin>>a[i];
    for(int i=1;i<n;i++)
    {
        if(a[i]==pre) 
            pre=0;
        else if(abs(a[i]-pre)==1)
            pre=1;
        else
        {
            flag=1;
            break;  
        }
    }
    if(flag) cout<<"NO";
    else
    {
        if(a[n]!=pre) flag=1;
        if(!flag) cout<<"YES";
        else cout<<"NO";
    }
    return 0;
}
上一篇:教你一招!如何通过Java面试(Spring篇)


下一篇:latex font