1 条题解

  • 0
    @ 2026-5-7 19:01:49

    我第一眼看到这个题时,立马就想到了暴力。

    枚举 kk ,把前 kk 个数和接下来 kk 个数从小到大排序然后一一比大小,出现前面 kk 个里的第几个数大于等于后面 kk 个里的第几个数就排除掉。

    然后想到优化:

    1. 从后往前枚举,最先找到的正确的那个就是答案。

    2. kk 的最大值为 n/2n/2 ,因为如果大于这个数,加下来的数就凑不齐k个了。

    3. 既然给了 mm 那就一定是有用的,记录下最早的那个 mm , kk 值一定是比这个 mm 所在序号小的,因为后面不可能到比最大值还大的数。

    4. 用桶排。 sortsort 一定是会炸的。

    就下来就是代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    int m,n,ji=1000000000,f[20010],fa[2010],fb[2010],chu,o;
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    int check(int x){
        int oo=1;
    	for(int i=1;i<=x;i++)
    		fa[f[i]]+=1;
    	for(int i=x+1;i<=2*x;i++)
    		fb[f[i]]+=1;
    	int a=1,b=1;
    	for(int i=1;i<=x;i++){
    		while(!fa[a])a++;
    		while(!fb[b])b++;
    		if(a>=b)oo=0;
    		fa[a]--;
    		fb[b]--;
    	}
    	return oo;
    }
    int main(){
    	m=read();
    	n=read();
    	for(int i=1;i<=n;i++){
    		f[i]=read();
    		if(f[i]==m&&o==0){
    			o=1;
    			ji=i;
    		}
    	}
    	ji=min(ji-1,n/2);
    	for(int i=ji;i>=1;i--)
    		if(check(i)){
    			chu=i;
    			break;
    		}
    	cout<<chu;
    	return 0;
    }
    
    • 1

    信息

    ID
    3625
    时间
    1000ms
    内存
    64MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者