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.

在这里插入图片描述
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.

样例输入
【样例15
1 0 2 0 1
【样例25
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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值