序列改变 (分析题)

来源:互联网 发布:唐国强演技怎么样知乎 编辑:程序博客网 时间:2024/06/16 09:30



给定一个序列 {a1 a2 a3 a4 a5......},判断是否存在一个数 val 使得对于任意一个数 ai 经过+val,-val的操作,或不进行操作后(即每次操作结束后 对应ai可能会变为ai+val,ai-val,ai中的一种)使得序列中的每一个数相等 
若存在这个数 val  则输出YES 否则输出 NO。

input
第一行为一个数n (1<=n<1e5)
第二行为序列中的数ai (1<=ai<1e9)

output
输出一行
若存在val 则输出“YES”
否则输出 “NO”

Sample in
5
1 3 3 1 2

Sample out
YES



思路: 刚开始看到这个题 还以为是二分答案 o(nlogn) 1000ms 应该能过。码代码的时候 看到样例突然想明白了,并不需要二分,只要理解这个val是个定值就可以了。

1.假设存在val  那么序列中相同的数 只需执行相同的操作就可以了。
2.去重升序排序后  思考,对于每个数只进行3种操作中的一种 则可以推出每种操作最多只能有一个数(如果不是一个数 并且不存在重复 则两个数进行相同操作后的结果一定不同) 所以就可以理解为小学数学题  把一队人分成至多3队 要求每队中至多只有一个人。

问题就解决了

附代码


#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <map>#include <set>#include <vector>#include <queue>#include <stack>#include <math.h>using namespace std;int main(){    int n,k;    scanf("%d",&n);    set<int> num;    set<int>::iterator p;    for(int i=0;i<n;i++)/* 对于题意的要求 去重+排序 set很方便*/    {        scanf("%d",&k);        num.insert(k);    }    int have=num.size();    if(have>3)        printf("NO\n");    else if(have<3)  /* 序列中数少于两个 必然可以满足题意*/        printf("YES\n");    else    {        int div[4];        int i=0;        for(p=num.begin();p!=num.end();p++,i++)            div[i]=*p;        if(div[2]-(div[1]-div[0])==div[1])            printf("YES\n");        else            printf("NO\n");    }    return 0;}



1 0
原创粉丝点击