題目大意:給出一個長度為 n 的數(shù)列,以及一個數(shù)字 k ,每次操作可以將一段連續(xù)區(qū)間 [ l , r ] 內(nèi)的數(shù)字全部替換成該區(qū)間的中位數(shù),問能否通過適當(dāng)?shù)牟僮魇沟谜麄€數(shù)列的 n 個數(shù)字全部等于 k?
題目分析:首先不難看出,如果區(qū)間內(nèi)不存在數(shù)字 k 的話一定是 no ,然后我設(shè):
小于 k 的數(shù)為 -1
大于 k 的數(shù)為 1
等于 k 的數(shù)為 0
因為最終需要使得整個數(shù)列都變成中位數(shù),所以我們不妨一開始就對區(qū)間 [ 1 , n ] 進行討論,分為三種情況:sum 為區(qū)間和
如果 sum == 0 的話,說明等于 k 的數(shù)已經(jīng)位于中位數(shù)的位置了,顯然為 yes
如果 sum > 0 的話,說明大于 k 的數(shù)比較多,需要減少大于 k 的數(shù)量,因為此時經(jīng)過篩選后,區(qū)間內(nèi)一定存在等于 k 的數(shù),即一定存在著非正數(shù)( -1 和 0 ),與這些非正數(shù)相鄰的正數(shù)可以組成長度為 2 的區(qū)間,此時正數(shù)都可以根據(jù)規(guī)則被同化為非正數(shù),所以通過適當(dāng)?shù)牟僮骺梢允?sum 不斷減小,直到 sum == 0 ,所以這種情況也顯然為 yes
如果 sum < 0 的話,根據(jù)上面的思想,我們的目標(biāo)是令 sum 不斷增大,直到 sum == 0 為止,如果負數(shù)想要被同化為非負數(shù)的話,需要在長度至少為 3 的區(qū)間內(nèi),滿足:有一個負數(shù)以及兩個非負數(shù)才行
綜上所述,只要數(shù)列中存在著 相鄰,或者相隔為 1 的非負數(shù)就是yes
代碼: ?
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;int n,k,a[N];bool check()
{if(n==1&&a[1]>=0)return true;for(int i=1;i<=n;i++)if(a[i]&(a[i+1]|a[i+2]))return true;return false;
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int w;cin>>w;while(w--){scanf("%d%d",&n,&k);bool flag=false;for(int i=1;i<=n;i++){scanf("%d",a+i);if(a[i]==k)flag=true;a[i]=(a[i]>=k);}if(!flag){puts("no");continue;}a[n+1]=a[n+2]=0;if(check())puts("yes");elseputs("no");}return 0;
}