Codeforces Round #641 (Div. 2) D. Orac and Medians 题解(思维)

题目链接

题目大意

就是数组里一段数可以都变成他的中位数,问整个序列能不能变成k。可以变化很多次

题目思路

emmm,根本没什么思路,看了题解感觉根本想不到啊,但是仔细想想其实确实应该那么想。

先令a[i]==1(a[i]==k) a[i]==0(a[i]<k) a[i]==2(a[i]>k),因为是合并其实只要知道相对k的大小即可

其实肯定是想一次合并的时候先想合并区间小的,为什么呢,因为你区间太大,你不好想啊。。。那么首先考虑区间长度为2,你会发现要把他们全部变成1只有可能是1,2。你1,1变什么变。。。然后考虑区间长度为3,这个时候你会发现(0,1,2)以及里面包含2个及以上1都行,然后你会发现其实如果能变一堆2出来好像也不错,然后再和1和2两个合并就行。那么其实就很好想了。

那么只要包含1,并且如果一个长度为 3 的子区间中有 2 个数大于等于 k ,那么就能行

简单理解一下这个结论:

与 1 相邻有 2 那么就可以改掉它

  1. 如果我们两个 1 就显然可以改掉一个数,同理别的直接改就好了

  2. {0,1,2} 直接中位数

  3. {0,2,2} 我们改掉 0 变成 2 然后对于每个 0 我们都可以把它改 成 2,直到找到 1

代码

#include<cstdio>
using namespace std;
const int maxn=1e5+5;
int t,n,k,a[maxn];
int main(){
    scanf("%d",&t);
    while(t--){
        bool flag1=0,flag2=0;
        scanf("%d %d",&n,&k);
        for(int i=2;i<=n+1;i++){//防止数组下标为负数
            scanf("%d",&a[i]);
            if(a[i]<k){
                a[i]=0;
            }else if(a[i]==k){
                a[i]=1;
                flag1=1;
            }else{
                a[i]=2;
            }
            if(n==1||((a[i]>=1)+(a[i-1]>=1)+(a[i-2]>=1))>=2){//注意还有一个元素的情况
                flag2=1;
            }
        }
        printf("%s\n",(flag1&flag2)?"yes":"no");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值