Orac and Medians CodeForces - 1349B
原题链接
考察:思维
思路:
从小区间开始看:
- len==2,只有区间:k >k各一个,才能成功.只要出现了2个k,那么在len==3的区间内一定能成功.此时递推出yes.
- len==3,不考虑(k,>k)的区间长度=2的情况,假设区间内存在k,那么此时只有(<k,k,k)或者(k,<k,>k),(>k,<k,k) 才能成功转化.假设不存在k,我们可以发现(<k,>k,>k)的情况且数组存在k可以推到len==2的情况.
总结即判定长度为2的区间,和判定长度为3的区间即可.
Code
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,k,a[N];
bool check()
{
bool ok = 0;
for(int i=1;i<=n;i++)
if(a[i]==k) ok = 1;
if(!ok||n==1) return ok;
for(int i=2;i<=n;i++)// ==k >k
if(a[i-1]>k&&a[i]==k) return 1;
else if(a[i-1]==k&&a[i]>k) return 1;
int cnt[2];
memset(cnt,0,sizeof cnt);
for(int i=1,j=1;i<=n;i++)//<k >k >k
{
while(j<=n&&j-i<=2)
{
if(a[j]<k) cnt[0]++;
else cnt[1]++;
j++;
}
if(cnt[1]>cnt[0]) return 1;
if(j>n) break;
if(a[i]<k) cnt[0]--;
else cnt[1]--;
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
if(check()) puts("yes");
else puts("no");
}
return 0;
}