Orac and Medians

题意:

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

分析:

主要还是思考问题的角度,从部分推整体。
要达到目的,那么 \(k\) 必然要出现在数组 \(a\) 中。
把数组中的所有的数分成三类:\(0\) 表示小于 \(k\) 的数,\(1\) 表示等于 \(k\) 的数,\(2\) 表示大于 \(k\) 的数。
\(n=1\) 时,直接判断。
\(n>1\) 时,
当有超过两个 \(1\) 连续时,必然可以通过以两个 \(1\) 为基础向左右一个一个的拓展来实现目的。
当只有单独的1时,
如果出现:\(12/21\) 的情况,可以转化为 \(11\),满足;
当出现: \(10/01\) 的情况,
取解于第三个数的情况,如果是 \(101/102\) 仍可以;但如果出现 \(100\) 则不满足情况。
因此,只要满足出现一次:两个均大于等于1的数之间的间距小于等于 \(2\),即可。
题解证明

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int main()
{
    int t,n,k;
    scanf("%d",&t);
    while(t--)
    {
        bool f=0,ff=0;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==k) ff=1;
        }
        if(n==1&&ff) f=1;
        if(ff&&!f)
        {
            int last=0;
            for(int i=1;i<=n;i++)
            {
                if(a[i]>=k)
                {
                    if(i-last<=2&&last>0)
                    {
                        f=1;
                        break;
                    }
                    last=i;
                }
            }
        }
        if(f) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/1024-xzx/p/12904356.html