题解

535 条题解

  • 0
    @ 2015-08-26 17:26:10

    这道题呢其实是用贪心算法,先寻找最小的两堆合并,但注意每合并一次都要重新排序。数据还是不大的,用long long能过。
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n;
    void insort(long w[],int x)
    {
    bool bo;
    int i,temp;
    for(i=x;i<=n-1;i++){
    bo=true;
    if(w[i]>w[i+1]){
    temp=w[i];
    w[i]=w[i+1];
    w[i+1]=temp;
    bo=false;
    }
    if(bo==true){
    break;
    }
    }
    }
    int main()
    {
    bool bo;
    long a[10001],sum[10001]={0};
    int i,tail=1,j,temp;;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
    scanf("%d",&a[i]);
    }
    for(i=1;i<=n-1;i++){
    do{
    bo=true;
    for(j=1;j<=n-i;j++){
    if(a[j]>a[j+1]){
    temp=a[j];
    a[j]=a[j+1];
    a[j+1]=temp;
    bo=false;
    }

    }
    }while(bo==false);
    if(bo==true){
    break;
    }
    }
    for(i=2;i<=n;i++){
    sum[tail]=a[i]+a[i-1];
    a[i]=sum[tail];
    insort(a,i);
    tail++;
    }
    for(i=2;i<tail;i++){
    sum[i]=sum[i-1]+sum[i];
    }
    printf("%d",sum[tail-1]);
    return 0;
    }

  • 0
    @ 2015-08-25 08:49:16

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,a[20001];
    long long ans=0;
    int main()
    {
    int temp,jj;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int minn;
    for(int g=1;g<n;g++)
    for(int i=0;i<=1;i++)
    {
    minn=999999999;
    for(int j=g+i;j<=n;j++)
    if(a[j]<minn) minn=a[j],jj=j;
    temp=a[g+i],a[g+i]=a[jj],a[jj]=temp;
    ans+=minn;
    if(i==1) a[g+1]+=a[g];
    }
    printf("%I64d\n",ans);
    return 0;
    }

  • 0
    @ 2015-08-09 13:49:33

    var heap:array[1..10000] of longint;
    i,num,n,size,a,b:longint;
    ans:int64;
    procedure put(x:longint);
    var son,fa,t:longint;
    begin
    inc(size); heap[size]:=x; son:=size;
    fa:=son div 2;
    while (son<>1) and (heap[fa]>heap[son]) do
    begin
    t:=heap[fa]; heap[fa]:=heap[son]; heap[son]:=t;
    son:=fa; fa:=son div 2;
    end;

    end;
    function get:longint;
    var fa,son,t:longint;
    begin
    get:=heap[1]; heap[1]:=heap[size]; dec(size); fa:=1;
    while (fa*2<=size) do
    begin
    if (fa*2+1>size) or (heap[fa*2]<heap[fa*2+1]) then
    son:=fa*2
    else
    son:=fa*2+1;
    if heap[fa]>heap[son] then
    begin
    t:=heap[fa]; heap[fa]:=heap[son]; heap[son]:=t; fa:=son;
    end
    else
    break;
    end;
    end;

    begin //main
    read(n); size:=0; fillchar(heap,sizeof(heap),0); ans:=0;
    for i:=1 to n do
    begin
    read(num); put(num);
    end;

    while size<>1 do
    begin
    a:=get; b:=get;
    ans:=a+b+ans; a:=a+b; put(a);
    end;

    write(ans);
    end.

  • 0
    @ 2015-08-06 15:31:23

    #include <cstdio>
    #include <algorithm>
    int main()
    {
    int n,w[10001],ans=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&w[i]);
    std::sort(w,w+n);
    for(int i=0;i<n-1;i++)
    {
    int x=w[i]+w[i+1];
    w[i+1]=x;ans+=x;
    for(int j=i+1;j<n-1;j++){
    if(w[j]>w[j+1]) {int t=w[j];w[j]=w[j+1];w[j+1]=t;}
    else break;}
    }
    printf("%d",ans);
    return 0;
    }

  • 0
    @ 2015-08-03 12:08:17

    测试数据 #0: Accepted, time = 62 ms, mem = 568 KiB, score = 10

    测试数据 #1: Accepted, time = 0 ms, mem = 564 KiB, score = 10

    测试数据 #2: Accepted, time = 0 ms, mem = 568 KiB, score = 10

    测试数据 #3: Accepted, time = 15 ms, mem = 568 KiB, score = 10

    测试数据 #4: Accepted, time = 15 ms, mem = 572 KiB, score = 10

    测试数据 #5: Accepted, time = 15 ms, mem = 572 KiB, score = 10

    测试数据 #6: Accepted, time = 46 ms, mem = 572 KiB, score = 10

    测试数据 #7: Accepted, time = 62 ms, mem = 564 KiB, score = 10

    测试数据 #8: Accepted, time = 62 ms, mem = 572 KiB, score = 10

    测试数据 #9: Accepted, time = 62 ms, mem = 572 KiB, score = 10

    选择排序也可以很快。。。虽然和插排没什么区别(一开始少排一次。。。)
    ####c++ code
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n;
    int a[20001];
    long long ans=0;
    int main()
    {
    int temp;
    int jj;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    int minn;
    for(int g=1;g<n;g++)
    for(int i=0;i<=1;i++)
    {
    minn=1000000000;
    for(int j=g+i;j<=n;j++)
    if(a[j]<minn)
    minn=a[j],jj=j;
    temp=a[g+i],a[g+i]=a[jj],a[jj]=temp;
    ans+=minn;
    if(i==1)
    a[g+1]+=a[g];
    }

    printf("%lld",ans);
    system("pause");
    return 0;
    }

  • 0
    @ 2015-07-16 16:11:24

    测试数据 #0: Accepted, time = 562 ms, mem = 668 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 668 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 668 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 668 KiB, score = 10
    测试数据 #4: Accepted, time = 78 ms, mem = 664 KiB, score = 10
    测试数据 #5: Accepted, time = 156 ms, mem = 668 KiB, score = 10
    测试数据 #6: Accepted, time = 656 ms, mem = 668 KiB, score = 10
    测试数据 #7: Accepted, time = 656 ms, mem = 668 KiB, score = 10
    测试数据 #8: Accepted, time = 593 ms, mem = 668 KiB, score = 10
    测试数据 #9: Accepted, time = 609 ms, mem = 668 KiB, score = 10
    Accepted, time = 3310 ms, mem = 668 KiB, score = 100

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;

    int a[100010];

    unsigned long long ans=0;

    int main()
    {
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);

    for(int i=1;i<n;i++)
    {
    sort(a+i,a+n+1);
    ans+=a[i]+a[i+1];
    a[i+1]+=a[i];
    a[i]=0;
    }
    printf("%lld",ans);
    }

    加油加油

  • 0
    @ 2015-07-06 11:08:11

    编译成功

    测试数据 #0: Accepted, time = 514 ms, mem = 391672 KiB, score = 10

    测试数据 #1: Accepted, time = 452 ms, mem = 391668 KiB, score = 10

    测试数据 #2: Accepted, time = 468 ms, mem = 391668 KiB, score = 10

    测试数据 #3: Accepted, time = 436 ms, mem = 391668 KiB, score = 10

    测试数据 #4: Accepted, time = 530 ms, mem = 391672 KiB, score = 10

    测试数据 #5: Accepted, time = 546 ms, mem = 391672 KiB, score = 10

    测试数据 #6: Accepted, time = 592 ms, mem = 391672 KiB, score = 10

    测试数据 #7: Accepted, time = 405 ms, mem = 391668 KiB, score = 10

    测试数据 #8: Accepted, time = 561 ms, mem = 391668 KiB, score = 10

    测试数据 #9: Accepted, time = 546 ms, mem = 391668 KiB, score = 10

    Accepted, time = 5050 ms, mem = 391672 KiB, score = 100

    反人类两亿数组桶排序终于AC了,看正常解法的移步楼下↓↓↓↓↓
    #include<bits/stdc++.h>
    using namespace std;
    long r,n,i,j,mi,s=0,sec=0;
    short int a[200000001];
    int main(){
    cin>>n;
    memset(a,0,sizeof(a));
    mi=20000;
    for (i=1;i<=n;i++){
    cin>>r;
    a[r]++;
    if (r<mi) mi=r;
    // if (r>max) max=r;
    }
    while (n!=1){
    if (a[mi]==0){
    mi++;
    continue;
    }
    a[mi]--;
    sec=mi;
    while (a[sec]==0) sec++;
    a[sec]--;
    s=s+mi+sec;
    a[mi+sec]++;
    n--;
    }

    cout<<s;
    return 0;
    }

  • 0
    @ 2015-07-04 11:28:59

    测试数据 #0: Accepted, time = 78 ms, mem = 252 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 252 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 252 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 248 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 252 KiB, score = 10
    测试数据 #5: Accepted, time = 15 ms, mem = 248 KiB, score = 10
    测试数据 #6: Accepted, time = 62 ms, mem = 252 KiB, score = 10
    测试数据 #7: Accepted, time = 62 ms, mem = 252 KiB, score = 10
    测试数据 #8: Accepted, time = 62 ms, mem = 248 KiB, score = 10

    测试数据 #9: Accepted, time = 62 ms, mem = 248 KiB, score = 10

    为何用那些**高端算法**?
    一遍快排就行了呀。

  • 0
    @ 2015-05-15 21:52:42

    最小的两个合并,STL优先队列最方便。

  • 0
    @ 2015-05-01 13:58:12

    var
    n,t,i,j,s,m:longint;
    heap:array[1..10000]of longint;

    procedure up(k:longint);
    begin
    while k>1 do
    if heap[k shr 1]>heap[k] then
    begin
    t:=heap[k shr 1];
    heap[k shr 1]:=heap[k];
    heap[k]:=t;
    k:=k shr 1;
    end
    else break;
    end;

    procedure down(k:longint);
    var temp:longint;
    begin
    while 2*k<=n do
    begin
    temp:=k;
    if heap[2*k]<heap[temp] then temp:=2*k;
    if (heap[2*k+1]<heap[temp])and(2*k+1<=n) then temp:=2*k+1;
    if temp=k then break;
    t:=heap[temp];
    heap[temp]:=heap[k];
    heap[k]:=t;
    k:=temp;
    end;
    end;

    begin
    readln(n);
    for i:=1 to n do
    begin
    read(heap[i]);
    up(i);
    end;
    for i:=1 to n-1 do
    begin
    m:=0;
    m:=m+heap[1];
    heap[1]:=heap[n];
    n:=n-1;
    down(1);
    m:=m+heap[1];
    heap[1]:=heap[n];
    n:=n-1;
    down(1);
    n:=n+1;
    heap[n]:=m;
    up(n);
    s:=s+m;
    end;
    write(s);
    end

  • 0
    @ 2015-04-30 20:52:21

    优先队列秒杀

    c++ code

    #include<cstdio>
    #include<queue>
    using namespace std;
    int main()
    {
    int n,ans=0,t;
    scanf("%d",&n);
    priority_queue<int,vector<int>,greater<int> > q;
    for (int i=0;i<n;++i) scanf("%d",&t),q.push(t);
    for (int i=1;i<n;++i)
    {
    int a=q.top(); q.pop();
    int b=q.top(); q.pop();
    ans+=a+b;
    q.push(a+b);
    }
    printf("%d",ans);
    return 0;
    }

  • 0
    @ 2015-04-24 21:30:44

    用c++ stl中的优先队列水过
    #include<iostream>
    #include<queue>
    #include<vector>
    using namespace std;
    priority_queue<int,vector<int>,greater<int> > q;
    int n,t,t1,s=0;
    int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
    cin>>t;
    q.push(t);
    }
    for(int i=0;i<n-1;i++){
    t=q.top();
    q.pop();
    t1=q.top();
    q.pop();
    q.push(t1+t);
    s+=t1+t;
    }
    cout<<s;
    return 0;
    }

    • @ 2015-09-04 20:52:41

      #include <functional>

  • 0
    @ 2015-04-06 20:45:59

    一个单调队列的实现,有效的把时间复杂度拉到O(n)(除了sort)
    ###block code
    #include <cstdio>
    #include <algorithm>
    #define oo 2147483647
    using namespace std;
    int a[100000],b[100000],ha=1,hb=1;
    int ta=0,tb=0;
    int ans=0;

    int popa()
    {
    return a[ha++];
    }

    int popb()
    {
    return b[hb++];
    }

    void pushb(int x)
    {
    ans+=b[++tb]=x;
    return;
    }

    int main()
    {
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);
    ta=n;
    for(int i=1;i<n;i++)
    {
    int sum=0;
    for(int j=1;j<3;j++)
    {
    if(hb>tb)sum+=popa();else if(ha>ta)sum+=popb();
    else if(a[ha]<b[hb])sum+=popa();else sum+=popb();
    }
    pushb(sum);
    }
    printf("%d",ans);
    //fclose(stdin);
    //fclose(stdout);
    return 0;
    }

  • 0
    @ 2015-03-18 18:43:24

    贪心的算法+堆的数据结构就好啦~

    ###block code
    program ex;
    var heap:array[1..10000] of longint;
    i,num,n,size,a,b:longint;
    ans:int64;
    procedure put(x:longint);
    var son,fa,t:longint;
    begin
    inc(size); heap[size]:=x; son:=size;
    fa:=son div 2;
    while (son<>1) and (heap[fa]>heap[son]) do
    begin
    t:=heap[fa]; heap[fa]:=heap[son]; heap[son]:=t;
    son:=fa; fa:=son div 2;
    end;

    end;
    function get:longint;
    var fa,son,t:longint;
    begin
    get:=heap[1]; heap[1]:=heap[size]; dec(size); fa:=1;
    while (fa*2<=size) do
    begin
    if (fa*2+1>size) or (heap[fa*2]<heap[fa*2+1]) then
    son:=fa*2
    else
    son:=fa*2+1;
    if heap[fa]>heap[son] then
    begin
    t:=heap[fa]; heap[fa]:=heap[son]; heap[son]:=t; fa:=son;
    end
    else
    break;
    end;
    end;

    begin //main
    read(n); size:=0; fillchar(heap,sizeof(heap),0); ans:=0;
    for i:=1 to n do
    begin
    read(num); put(num);
    end;

    while size<>1 do
    begin
    a:=get; b:=get;
    ans:=a+b+ans; a:=a+b; put(a);
    end;

    write(ans);
    end.

  • 0
    @ 2014-10-26 19:25:51

    var
    i,n,nn,x,y,sum,summ,k,xx:longint;
    a,b:array[0..10000] of longint;
    procedure qsort(l,r:longint);
    var
    k,x,i,j,t,temp:longint;
    begin
    i:=l;
    j:=r;
    k:=(i+j) div 2;
    t:=a[k];
    repeat
    while (t>a[i]) do inc(i);
    while (t<a[j]) do dec(j);
    if i<=j then
    begin
    temp:=a[i];
    a[i]:=a[j];
    a[j]:=temp;
    inc(i);
    dec(j);
    end;
    until i>j;
    if j>l then qsort(l,j);
    if i<r then qsort(i,r);
    end;

    begin

    readln(n);
    nn:=n;
    fillchar(a,sizeof(a),0);
    for i:=1 to n do
    read(a[i]);
    qsort(1,n);
    x:=1;
    y:=1;
    k:=0;
    while (x<=n)or(y<=k) do
    begin
    if ((a[x]>b[y])and(y<=k)and(k>0))or(x>n) then
    begin
    sum:=sum+b[y];
    inc(y);
    end else
    begin
    sum:=sum+a[x];
    inc(x);
    end;
    inc(xx);
    if xx=2 then
    begin
    xx:=0;
    inc(k);
    b[k]:=sum;
    summ:=summ+sum;
    sum:=0;
    end;
    end;
    writeln(summ);
    end.

    淳朴的方法

  • 0
    @ 2014-10-15 17:05:34

    #include<iostream>
    #include<queue>
    using namespace std;
    priority_queue<int>q;
    main()
    {
    int n,i,x,a=0,t;
    cin>>n;
    for(i=0;i<n;i++)
    {
    cin>>x;
    q.push(-x);
    }
    for(i=1;i<n;i++)
    {
    t=q.top();
    a-=q.top();
    q.pop();
    t+=q.top();
    a-=q.top();
    q.pop();
    q.push(t);
    }
    cout<<a;
    }

  • 0
    @ 2014-09-06 10:37:40

    最小堆水题。(新版vijosUI真不错,过题很有快感……)
    #include<stdio.h>

    void swap(int* a,int* b)
    {
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
    }

    void minheapify(int* heap,int root,int heapSize)
    {
    int smallest;
    int left=2*root;
    int right=2*root+1;
    if(left<=heapSize && heap[left]<heap[root])
    smallest=left;
    else
    smallest=root;
    if(right<=heapSize && heap[right]<heap[smallest])
    smallest=right;
    if(smallest!=root)
    {
    swap(&heap[smallest],&heap[root]);
    minheapify(heap,smallest,heapSize);
    }
    }

    void buildHeap(int* heap,int heapSize)
    {
    int i;
    for(i=heapSize/2;i>=1;i--)
    minheapify(heap,i,heapSize);
    }

    int mergefruits(int* heap,int* heapSize)
    {
    int currentMin;
    int result=0;
    while(*heapSize!=1)
    {
    currentMin=heap[1];
    heap[1]=heap[*heapSize];
    (*heapSize)--;
    minheapify(heap,1,(*heapSize));
    currentMin+=heap[1];
    result+=currentMin;
    heap[1]=currentMin;
    minheapify(heap,1,(*heapSize));
    }
    return result;
    }

    int main()
    {
    int inputArray[10001];
    int i,amount,heapSize;
    scanf("%d",&amount);
    heapSize=amount;
    for(i=1;i<=amount;i++)
    scanf("%d",&inputArray[i]);
    buildHeap(inputArray,amount);
    printf("%d",mergefruits(inputArray,&heapSize));
    return 0;
    }

  • 0
    @ 2014-08-27 19:33:17

    用优先队列

    评测结果

    编译成功

    测试数据 #0: Accepted, time = 31 ms, mem = 844 KiB, score = 10

    测试数据 #1: Accepted, time = 0 ms, mem = 556 KiB, score = 10

    测试数据 #2: Accepted, time = 0 ms, mem = 572 KiB, score = 10

    测试数据 #3: Accepted, time = 0 ms, mem = 576 KiB, score = 10

    测试数据 #4: Accepted, time = 15 ms, mem = 636 KiB, score = 10

    测试数据 #5: Accepted, time = 31 ms, mem = 708 KiB, score = 10

    测试数据 #6: Accepted, time = 31 ms, mem = 840 KiB, score = 10

    测试数据 #7: Accepted, time = 31 ms, mem = 836 KiB, score = 10

    测试数据 #8: Accepted, time = 31 ms, mem = 840 KiB, score = 10

    测试数据 #9: Accepted, time = 31 ms, mem = 840 KiB, score = 10

    Accepted, time = 201 ms, mem = 844 KiB, score = 100

  • 0
    @ 2014-08-12 16:13:04

    服务器快就贪心。慢就排序。

  • 0
    @ 2014-08-12 16:11:39

    ddd

信息

ID
1097
难度
6
分类
贪心 点击显示
标签
递交数
23906
已通过
6330
通过率
26%
被复制
41
上传者