最近数据结构刚好学了哈夫曼树,又刚好要学优先队列,这道题算是赶巧了。
一开始暴力写了一发,一看果然有点悬,922ms过的。改成优先队列。我的手写优先队列实在是太龊了,不过毕竟算是进步,记录一下。
调试了好久,总算写出来,多练练,慢慢得就精简了,加油。
下面是我的两份代码:
1.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define INF 2000000000
int cmp(const void *a,const void *b)
{
return *(long long *)a-*(long long *)b;
}
long long a[1000005];
int main()
{
long long n,i,j,k,l,sum;
while(scanf("%lld",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
qsort(a+1,n,sizeof(a[1]),cmp);
for(i=1,sum=0;i<n;i++)
{
sum+=(a[i]+a[i+1]);
a[i+1]=a[i]+a[i+1];
for(j=i+1;j<n;j++)
{
if(a[j]>a[j+1])
{
l=a[j];
a[j]=a[j+1];
a[j+1]=l;
}
else
break;
}
}
printf("%lld\n",sum);
}
return 0;
}
2.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define INF 2000000000
long long a[1000005];
struct node
{
long long p;
long long ls;
long long rs;
long long da;
}nn[1000005];
int main()
{
long long n,i,j,k,l,sum,tot,pa,x,y,z,h,temp;
while(scanf("%lld",&n)!=EOF)
{
sum=0;tot=0;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
tot++;
nn[tot].p=(tot%2==0?tot/2:(tot-1)/2);
nn[tot].ls=-1;
nn[tot].rs=-1;
nn[tot].da=a[i];
pa=nn[tot].p;
if(tot%2==0)
nn[pa].ls=tot;
else
nn[pa].rs=tot;
x=tot;
while(nn[x].p!=0&&nn[x].da<nn[nn[x].p].da)
{
y=nn[x].p;
temp=nn[x].da;
nn[x].da=nn[y].da;
nn[y].da=temp;
x=y;
}
}
/*printf("a%lld\n",tot);
for(i=1;i<=tot;i++)
printf("%lld ",nn[i].da);
printf("\n");
for(i=1;i<=tot;i++)
printf("%lld %lld %lld %lld\n",nn[i].ls,nn[i].rs,nn[i].p,nn[i].da);*/
while(tot>1)
{
sum+=nn[1].da;
h=nn[1].da;
nn[1].da=nn[tot].da;
if(tot%2==0)
nn[tot/2].ls=-1;
else
nn[(tot-1)/2].rs=-1;
tot--;
x=1;
while((nn[x].ls!=-1&&nn[nn[x].ls].da<nn[x].da)||(nn[x].rs!=-1&&nn[nn[x].rs].da<nn[x].da))
{
y=-1;
if(nn[x].ls!=-1&&nn[nn[x].ls].da<nn[x].da)
{
y=nn[x].ls;
}
if(nn[x].rs!=-1&&nn[nn[x].rs].da<nn[x].da)
{
if(y==-1)
y=nn[x].rs;
else
{
if(nn[nn[x].rs].da<nn[y].da)
y=nn[x].rs;
}
}
temp=nn[x].da;
nn[x].da=nn[y].da;
nn[y].da=temp;
x=y;
}
/*printf("c%lld\n",h);
for(i=1;i<=tot;i++)
printf("%lld ",nn[i].da);
printf("\n");*/
/*for(i=1;i<=tot;i++)
printf("%lld %lld %lld %lld\n",nn[i].ls,nn[i].rs,nn[i].p,nn[i].da);*/
sum+=nn[1].da;
h+=nn[1].da;
nn[1].da=nn[tot].da;
if(tot%2==0)
nn[tot/2].ls=-1;
else
nn[(tot-1)/2].rs=-1;
tot--;
x=1;
/*for(i=1;i<=tot;i++)
printf("#%lld %lld %lld %lld\n",nn[i].ls,nn[i].rs,nn[i].p,nn[i].da);*/
while((nn[x].ls!=-1&&nn[nn[x].ls].da<nn[x].da)||(nn[x].rs!=-1&&nn[nn[x].rs].da<nn[x].da))
{
//printf("yyy");
y=-1;
if(nn[x].ls!=-1&&nn[nn[x].ls].da<nn[x].da)
{
y=nn[x].ls;
}
if(nn[x].rs!=-1&&nn[nn[x].rs].da<nn[x].da)
{
if(y==-1)
y=nn[x].rs;
else
{
if(nn[nn[x].rs].da<nn[y].da)
y=nn[x].rs;
}
}
temp=nn[x].da;
nn[x].da=nn[y].da;
nn[y].da=temp;
x=y;
}
/*printf("d%lld\n",h);
for(i=1;i<=tot;i++)
printf("%lld ",nn[i].da);
printf("\n");*/
tot++;
nn[tot].p=(tot%2==0?tot/2:(tot-1)/2);
nn[tot].ls=-1;
nn[tot].rs=-1;
nn[tot].da=h;
pa=nn[tot].p;
if(tot%2==0)
nn[pa].ls=tot;
else
nn[pa].rs=tot;
x=tot;
while(nn[x].p!=0&&nn[x].da<nn[nn[x].p].da)
{
y=nn[x].p;
temp=nn[x].da;
nn[x].da=nn[y].da;
nn[y].da=temp;
x=y;
}
/*printf("*%lld\n",sum);
for(i=1;i<=tot;i++)
printf("%lld ",nn[i].da);
printf("\n");*/
}
printf("%lld\n",sum);
}
return 0;
}
虽然我的代码风格已经被无数次吐槽,不过还是忍不住,义无反顾的各种手写,无脑乱写。。。
慢慢改正吧。其实多手写,多练练代码能力还是不错的哈。(只要别把代码风格带坏。。。)