链接:SDUT 2023 Summer Individual Contest - 5(for 22) - Virtual Judge (vjudge.net)
题目大意:
设某个数组的中位数是这个数组在事先排序后的中间值。如果数组长度为偶数,则设中位数为中间两个元素中最小的一个。例如,数组[10,3,2,3,2]的中位数是3(即[2,2,3,3,10])。数组[1,5,8,1]的中位数为1(即[1,1,5,8])。如果数组的中值大于等于m,则该数组为m-good。设数组[a1, a2,…],和]是子数组{b1, b2,…, bk}使得b1 =[a1, a2, ai1], b2 = [ai1 + 1、+ 2,ai2], bk = [aik-1 + 1, aik-1 + 2,,一个)。例如,array[10 3 2 3 2]可以分割如下:{[10 3 2 3 2]}或{[10],[3],[2],[3],[2]},或{[10],[3、2、3、2]},或{[10 3],[2],[3 2]}等等。给定长度为n的整数数组a,求a被划分为最大数目的子数组,使每个子数组都是m-good。
思路:其实这个题可以把数组转化成01的形式,如果大于等于m的变为1,否则变为0;然后我们应当明白一件事,就是当一个分区内1的数量大于0时才可以符合中位数大于等于m这件事。所以我们可以让每一个成立的分区内1的数量比0的数量多1,这样便可以让分区数量最大化。然后就开始从第一个数开始遍历,如果是1就c1++,是0就c0++,c1和c0这两个数只有一个数为正,这两个相互抵消。如果最后c0为正则代表没有分区,c1为正的话就代表有c1个分区。这c1个分区中包含着1和n(n>=0)个(0,1),相互抵消的只有01,而不是其决定作用的1.
代码:
#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long
const int N=1e5;
int n,m,k,x,v,vv,y,xx,yy;
int c[8],a[222222];
set<int>s;
set<char>t[56],ts[56];
map<int,int>mp,mk;
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
int u;
cin>>u;
if(u>=m)a[i]=1;
else a[i]=0;
}
int c1=0,c0=0;
for(int i=1;i<=n;i++){
if(a[i]==1){
c1++;
if(c0){
c0--;c1--;
}
}
else{
c0++;
if(c1){
c1--;c0--;
}
}
}if(c1<0){
cout<<0<<endl;return ;
}
cout<<c1;
}
signed main(){
int T=1;
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// cin>>T;
while(T--){
solve();
}
}