1 solutions
-
1
暴力的做法是肯定爆空间的,因为这题数据有五次方,故暴力做法只拿了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