浅谈YKH算法
显然,对于小范围数据,我们最容易想到的就是nn的暴力做法 ,但是对于大范围数据暴力是不行的。这时候我们就像到了优化。如果能把它优化到nn能过的数据就行了。我们知到两个大数相加肯定是一个更大的数,所以我们只要把多余的大数去掉即可。(对于超过1000的n,我们就把它砍到1000)保险起见先sort两遍,然后砍数据,最后得出来<=1000000的数我们再sort一遍。输出前n个即可。下面是代码。
#include<bits/stdc++.h>
using namespace std;
int n,nn,a[100005],b[100005],c[25000005],tot;
int read()
{
int x=0;char c;bool f;
f=true;
c=getchar();
if (c=='-') f=false;
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
if (f==false) x=x*-1;
return x;
}
int main()
{
// freopen("xulie.in","r",stdin);
// freopen("xulie.out","w",stdout);
n=read();
for (int i=1;i<=n;i++)
a[i]=read();
for (int i=1;i<=n;i++)
b[i]=read();
sort(1+a,1+a+n);
sort(1+b,1+b+n);
nn=n;
tot=0;
if (n>1000) nn=1000;
for (int i=1;i<=nn;i++)
for (int j=1;j<=nn;j++)
{
tot++;
c[tot]=a[i]+b[j];
}
sort(1+c,1+c+tot);
for (int i=1;i<=n;i++)
printf("%d ",c[i]);
return 0;
}
但是,这种做法可能会有反例(虽然目前没找到,程序也能过所有数据)。我们这时候就可以用大根堆优化,先把a[1]与所有的bi做一遍加法,得出n个初始值,然后再从a[2]开始与所有的b[i]做加法,一旦找到一个a[j]+b[i]是比堆头大的,就直接退出然后输出。下面是代码。
#include<bits/stdc++.h>
using namespace std;
int read()
{
int x=0;char c;bool f;
f=true;
c=getchar();
if (c=='-') f=false;
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
if (f==false) x=x*-1;
return x;
}
priority_queue<int> k;
int n,a[100010],b[100010],ans[100010];
int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) b[i]=read();
sort(a+1,a+1+n);
sort(b+1,b+1+n);
for(int i=1;i<=n;i++) k.push(a[1]+b[i]);
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++)
if(k.top()>a[i]+b[j]){
k.pop();
k.push(a[i]+b[j]);
}else break;
for(int i=n;i>=1;i--) ans[i]=k.top(),k.pop();
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
puts("");
return 0;
}
注意细节!!!

浙公网安备 33010602011771号