1 solutions

  • 1
    @ 2025-5-20 22:53:11

    暴力的做法是肯定爆空间的,因为这题数据有五次方,故暴力做法只拿了50分就遗憾离场

    我们知道,a、b两个数组可以形成形如:

    a1+b1 a1+b2 a1+b3...a1+bn

    a2+b1 a2+b2 a2+b3...a2+bn

    ...

    an+b1 an+b2 an+b3...an+bn

    的n个数列

    又因为ab均为不下降排序,则如果ai+bi不是最小的n个,ai+b(i+1)~ai+bn都不符合,就break,枚举下一行

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    int a[100005]={},b[100005]={};
    int p[1000005]={};
    int tot=0;
    void up(int x){
    	int t=(x>>1);
    	if(x==1||p[t]>p[x]) return;
    	swap(p[x],p[t]);
    	up(t);
    }
    void psh(int x){
    	p[++tot]=x;
    	up(tot);
    }
    void dn(int x){
    	int t=(x<<1);
    	if(t>tot) return;
    	if(t+1<=tot) t=(p[(x<<1)]>p[(x<<1)+1])?(x<<1):(x<<1)+1;
    	if(p[t]>p[x]){
    		swap(p[t],p[x]);
    		dn(t);
    	}
    }
    void pp(){
    	swap(p[1],p[tot--]);
    	dn(1);
    }
    //以上均为手打大根堆 
    int ans[100005]={};
    signed main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<=n;i++) cin>>b[i];
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			int sum=a[i]+b[j];
    			if(tot<n){//没有填满就加 
    				psh(sum);
    			}else{
    				if(sum<p[1]){//有更小的 
    					pp();
    					psh(sum);
    				}else break;//不入列,该行退出 
    			}
    		}
    	}
    	for(int i=n;i>=1;i--){//因为是大根堆,所以倒序输出 
    		ans[i]=p[1];
    		pp();
    	}
    	for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
    	return 0;
    }
    
    • 1

    Information

    ID
    361
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    7
    Tags
    # Submissions
    45
    Accepted
    11
    Uploaded By