【CF-1350 D. Orac and Medians】 思维

Orac and Medians

题意

给出一个长度为n的数组a,以及数字k,在一次操作中可以选择一个区间([l,r])
把这个区间里所有的数字变成其中位数,数组a的中位数是排好序之后的(a[frac{n+1}{2}])

问是否可以通过有限次操作,把整个区间变成k

思路

中文题解

我的理解:

把a中小于k的看做0等于k的看做1大于k的看做2

现在的目标就是n个数字变成1

  1. a中没有1,输出no,很显然

  2. a中存在至少两个连续的1,肯定可以:每次操作把全是1的一个区间,

    向左或者右扩展一个作为操作区间,新的区间全变成1,依次操作最后n个数字就全为1了。

  3. 如果a中最多只有连续的一个1

    1. 这时如果存在一个1和2相邻

      第一次选择12两个数字,就产生了连续的两个1,和第二种情况相同,可以

    2. 如果所有的1都和0相邻的:

      1. 如果存在102这种情况,第一次选择102,这样就得到了111,转为情况2,可以
      2. 如果存在22或者202,类似于情况2,向左右扩展变成2,就可以让1的相邻位置产生2,变成情况3的第一种,可以
    3. 其他情况无法得到连续的两个1,不可以

综上所述,只要存在k,并且存在两个相差小于等于2的位置上的数字大于等于k就可以。

特判n==1

代码

/*Gts2m ranks first in the world*/
#define pb push_back
#define stop system("pause")
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<string>
#include<algorithm>
#include<iostream>
// #include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
typedef unsigned long long ull;

int arr[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++)
            scanf("%d",&arr[i]);
        int flag=0;
        for(int i=1;i<=n;i++)
        {
            if(arr[i]==k)
                flag=1;
        }
        if(flag==0)
        {
            printf("no
");
            continue;
        }
        flag=0;
        for(int i=1;i<n;i++)
        {
            if(arr[i]>=k)
            {
                if(arr[i+1]>=k) flag=1;
                if(i+2<=n&&arr[i+2]>=k) flag=1;
            }
        }
        if(n==1) flag=1;
        if(flag) printf("yes
");
        else printf("no
");
   }
    return 0;
}
原文地址:https://www.cnblogs.com/valk3/p/12890577.html