洛谷 P1392 取数

题面

在做这道题前,先要会他的弱化版(实际一模一样,只是愚蠢的洛谷评测级别差了一档(睿智如姬无夜))

----------------------------------弱化版---------------------

弱化版

实际只是把矩阵行数改成两行而已

sol:先排序,后考虑一个序列a[1]+b[1],a[2]+b[1],a[3]+b[1],······,a[n-1]+b[1],a[n]+b[1];

显然对于上一个序列而言 a[1]+b[1]<=a[1]+b[2], a[2]+b[1]<=a[2]+b[2], a[3]+b[1]<=a[4]+b[2]

虽然上面反应的只是以a分成的n个组中a[i]+(b[1]到b[2]到b[3]···到b[n])每组序列严格递增

但是利用小根堆就可以完成要求了每次弹出堆顶元素,在压入弹出元素组别的下一个数

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100005;
int n,a[N],b[N],size=0,to[N];
struct node{int key,id;}heap[N*2];
inline void Up(int x)
{
    while(x>0)
    {
        if(heap[x].key<heap[x/2].key)
        {
            swap(heap[x],heap[x/2]); x/=2;
        }else break;
    }return;
}
inline void Down(int x)
{
    int y=x*2;
    while(y<=size)
    {
        if(y<size&&heap[y].key>heap[y+1].key)y++;
        if(heap[x].key>heap[y].key)
        {
            swap(heap[x],heap[y]); x=y; y=x*2;
        }else break;
    }return;
}
inline void Insert(int v,int id){heap[++size]=(node){v,id};Up(size);}
inline node Top(){return heap[1];}
inline void Pop(){swap(heap[1],heap[size]);size--;Down(1);}
int main()
{
    int i; node tmp; scanf("%d",&n);
    for(i=1;i<=n;i++)scanf("%d",&a[i]); for(i=1;i<=n;i++)scanf("%d",&b[i]); sort(a+1,a+n+1); sort(b+1,b+n+1);
    for(i=1;i<=n;i++){Insert(a[i]+b[1],i);to[i]=1;}
    for(i=1;i<=n;i++)
    {
        tmp=Top(); Pop(); printf("%d ",tmp.key); Insert(a[tmp.id]+b[++to[tmp.id]],tmp.id);
    }printf("\n");
}

----------------------------------强化版---------------------

这就是对于第一行,和第二行合并,得到新的序列,在用新序列与下一个合并,就解决了

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1005;
int n,m,k,a[2][N],b[N],size=0,to[N];
struct node{int key,id;}heap[N*2];
inline void Up(int x)
{
    while(x)
    {
        if(heap[x].key<heap[x/2].key)
        {
            swap(heap[x],heap[x/2]); x/=2;
        }else break;
    }return;
}
inline void Down(int x)
{
    int y=x*2;
    while(y<=size)
    {
        if(y<size&&heap[y].key>heap[y+1].key)y++;
        if(heap[x].key>heap[y].key)
        {
            swap(heap[x],heap[y]); x=y; y=x*2;
        }else break;
    }return;
}
inline void Insert(int key,int id){heap[++size]=(node){key,id};Up(size);}
inline node Top(){return heap[1];}
inline void Pop(){swap(heap[1],heap[size]);size--;Down(1);}
int main()
{
    int i,j,t=0; node tmp; scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=m;i++)scanf("%d",&a[t][i]); sort(a[t]+1,a[t]+m+1);
    for(i=2;i<=n;i++)
    {
        t^=1; for(j=1;j<=m;j++)scanf("%d",&b[j]); sort(b+1,b+m+1); size=0;
        for(j=1;j<=k;j++)
        {
            Insert(a[t^1][j]+b[1],j); to[j]=1;
        }
        for(j=1;j<=k;j++)
        {
            tmp=Top(); Pop(); a[t][j]=tmp.key; Insert(a[t^1][tmp.id]+b[++to[tmp.id]],tmp.id);
        }
    }for(i=1;i<=k;i++)printf("%d ",a[t][i]);
}

 

posted @ 2018-09-24 15:24  yccdu  阅读(286)  评论(0编辑  收藏  举报