題解:CF1349B Orac and Medians

一只小咕咕發表於2024-07-22

洛谷 | CF

刷一些 CF2000,進行一個錄的記。

思路記錄

  1. 首先觀察到數列裡的數不能憑空產生,所以初始序列必須含 \(k\)
  2. 由於兩個數的中位數是較小的那個,所以只要有一個與數列裡的 \(k\) 相鄰且比 \(k\) 大的數,就可以擴充套件到整個序列。
  3. 發現可以把第二條推廣一下,不必要和 \(k\) 相鄰,因為只要有兩個相鄰的比 \(k\) 大的數,就可以進行擴充套件到與 \(k\) 相鄰。
  4. 問題就來到了如何產生一段長度大於 \(1\) 的比 \(k\) 大的數列。第三條是一種方法,還有一種就是兩個大於 \(k\) 的數之間間隔一個任意數。(可以自己造幾組樣例手玩一下)

至此問題就得到了解決,一組資料時間複雜度 \(\mathcal{O(n)}\)

程式碼

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
inline int read();
int T;
int n,k,a[N];
int main()
{
	T=read();
	while(T--)
	{
		bool flag=0;
		n=read();k=read();
		for(int i=1;i<=n;i++) a[i]=read();
		if(n==1&&a[1]==k) {puts("yes");continue;}
		for(int i=1;i<=n;i++) if(a[i]==k) flag=1;
		if(!flag) {puts("no");continue;}
		else flag=0;
		for(int i=2;i<=n;i++)
		{
			if(a[i-1]>=k&&a[i]>=k) {puts("yes"),flag=1;break;}
		} 
		if(!flag)
		for(int i=2;i<n;i++)
		{
			if(a[i-1]>=k&&a[i+1]>=k) {puts("yes"),flag=1;break;}
		}
		if(!flag) puts("no");
	}
	return 0;
}

inline int read()
{
	int x=0,f=1;
	char ch;
	ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-') f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')
	{
		x=(x<<1)+(x<<3)+(ch&15);
		ch=getchar();
	}
    return x*f;
}