`
暴风雪
  • 浏览: 389218 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[堆排序]poj 2823:Sliding Window

阅读更多

 

大致题意:

    给出一列共n个数,和一个正整数k。对于所有的大于等于1,小于等于n-k的数i,求出在[i,i+k]这个区间中最大的数和最小的数  

大致思路:    

    借鉴 依然 的思路,要了解堆排序的大致运转方式以及堆内元素之间的调整过程。

 

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax=1000050;
int num[nMax],heap[nMax];
int n,heapsize;
int pos[nMax];   //表示数组第i个元素在堆内的位置。
int id[nMax];    //堆内第i个元素对应的数组下标.
int leftson(int a){return a<<1;}
int rightson(int a){return (a<<1)+1;}
int parent(int a){return a>>1;}
void exchange(int a,int b){   //交换堆内a位置和b位置的元素
    int tmp;
    tmp=pos[id[a]],pos[id[a]]=pos[id[b]],pos[id[b]]=tmp;
    //swap(pos[id[a]],pos[id[b]]);
    tmp=id[a],id[a]=id[b],id[b]=tmp;
    tmp=heap[a],heap[a]=heap[b],heap[b]=tmp;
}

void minheap(int loc){      //以loc向下调整,为loc找到正确的位置,建立小根堆~~
    int tmp=loc,l=leftson(loc),r=rightson(loc);
    if(l<=heapsize&&heap[l]<heap[tmp])tmp=l;
    if(r<=heapsize&&heap[r]<heap[tmp])tmp=r;
    if(loc!=tmp){
        exchange(loc,tmp);
        minheap(tmp);
    }
}

void maxheap(int loc){      ////以loc向下调整,为loc找到正确的位置,建立大根堆~~
    int tmp=loc,l=leftson(loc),r=rightson(loc);
    if(l<=heapsize&&heap[l]>heap[tmp])tmp=l;
    if(r<=heapsize&&heap[r]>heap[tmp])tmp=r;
    if(loc!=tmp){
        exchange(loc,tmp);
        maxheap(tmp);
    }
}

void build(int f,int len){   //f=0时求小根堆,否则求大根堆   len:堆的大小
    int i;
    if(!f){
        for(i=len/2;i>0;i--){
            minheap(i);
        }
    }
    else{
        for( i=len/2;i>0;i--){
            maxheap(i);
        }
    }
}

void adjmin(int a){         //分别向下和向上找到堆中a位置元素应该在的位置
    minheap(a);
    while(a>1&&heap[parent(a)]>heap[a]){
        exchange(a,parent(a));
        a=parent(a);
    }
}

void adjmax(int a){
    maxheap(a);
    while(a>1&&heap[parent(a)]<heap[a]){
        exchange(a,parent(a));
        a=parent(a);
    }
}

int main(){
    int i,j,p;
    scanf("%d%d",&n,&heapsize);
    for(i=1;i<=n;i++){
        scanf("%d",&num[i]);
        heap[i]=num[i];
        pos[i]=id[i]=i;
    }
    build(0,heapsize);
    printf("%d ",heap[1]);
    for(i=heapsize+1;i<=n;i++){
        p=pos[i-heapsize];
        exchange(i, p);
        adjmin(p);
        printf("%d ",heap[1]);
    }printf("\n");
///////////////////////////   下面来求区间最大值
    for(i = 1;i<=n;i++){
        pos[i]=id[i]=i;
        heap[i]=num[i];
    }
    build(1,heapsize);
    printf("%d ",heap[1]);
    for(i=heapsize+1;i<=n;i++){
        p=pos[i-heapsize];
        exchange(i, p);
        adjmax(p);
        printf("%d ",heap[1]);
    }printf("\n");
    return 0;
}
0
0
分享到:
评论
2 楼 暴风雪 2012-01-27  
f12345 写道
这是一道经典的单调优化dp

主要是想自己实现一遍对排序啊,以前只在数据结构书上看到过的~~
1 楼 f12345 2012-01-26  
这是一道经典的单调优化dp

相关推荐

    [POJ2823]Sliding Window(单调队列)by_zgx优化最新版

    我的博客链接:http://blog.csdn.net/CABI_ZGX

    堆排序练习:POJ 2388

    标题“堆排序练习:POJ 2388”指的是一个关于使用堆排序算法解决编程竞赛问题的实践案例。在编程竞赛中,如POJ(Programming Online Judge)平台上的问题2388,参赛者经常需要高效地解决排序问题,而堆排序作为一种...

    经典 的POJ 分类

    - 堆优化的Dijkstra算法 - **题目示例**: - POJ 1860、POJ 3259:利用Dijkstra算法解决最短路径问题。 - POJ 1062、POJ 2253:涉及Bellman-Ford算法的应用场景。 - POJ 1125、POJ 2240:Floyd算法的典型实例。 ...

    POJ2092:计数排序,求第K大的元素

    在数组中找出第K大的元素,可以采用多种方法实现,如快速选择、堆排序或优先队列。这里我们可以利用已排序的数组,通过一次遍历找到第K个元素。也可以采用迭代或者递归的方式,逐步缩小查找范围。 在解决POJ2092...

    acm新手训练方案新手必备

    - POJ 1753: 排序相关问题 - POJ 2965: 排序应用实例 - **搜索**:包括深度优先搜索(DFS)、广度优先搜索(BFS)等。 - **示例题目**: - POJ 1328: DFS的应用 - POJ 2109: BFS的应用 - POJ 2586: 搜索技巧展示 -...

    poj2823.cpp.tar.gz_线段树

    在题目"poj2823"中,我们看到它被应用于寻找区域间的最大值和最小值。线段树通常用于解决动态规划问题,特别是在数组或序列上执行范围查询和修改时,能提供O(log n)的时间复杂度。 线段树的基本概念: 线段树是由一...

    acm训练计划(poj的题)

    - (poj1094):适用于有向无环图(DAG)的一种排序方式,表示事件发生的顺序。 5. **网络流**: - (poj3041, poj3020):探讨如何在网络中找到最大流的问题,常用算法包括福特-福克森算法等。 6. **匹配算法**: ...

    ACM北大训练

    - **定义**: 包括快速排序、归并排序和堆排序等,用于将数据按照一定顺序排列。 - **应用场景**: 应用于几乎所有需要对数据进行排序的场景。 - **示例题目**: - poj2388: 涉及排序问题,可用快速排序或归并排序解决...

    Sliding Window

    这是来自poj的一道关于单调队列的题目。分为max_qu和min_qu两部分来做。

    POJ1-7试题

    这是西北工业大学的POJ试题的答案,欢迎下载!

    直接插入排序练习:POJ 2388

    这个练习题目,"POJ 2388",显然是通过编程实现直接插入排序来解决一个特定的问题。在这个问题中,我们需要理解直接插入排序的机制,并能用Java语言编写出高效的代码。 直接插入排序的基本步骤如下: 1. 从第二个...

    poj题目分类

    * 堆:例如 poj2513。 * trie 树:例如 poj2513。 4. 简单搜索: * 深度优先搜索:例如 poj2488、poj3083、poj3009、poj1321、poj2251。 * 广度优先搜索:例如 poj3278、poj1426、poj3126、poj3087、poj3414。 ...

    poj部分水题代码

    POJ 2703:选择出行方式 **题目概述**: 本题目旨在通过编程的方式解决一个实际问题——选择最佳出行方式(步行或骑自行车)。题目给出了一种算法来决定在不同条件下应该采取哪种出行方式。 **代码解析**: - **...

    poj刷题指南

    网上整理的一些poj刷题指南。 poj地址:http://poj.org

    极角排序:POJ 1696(叉积+深搜)

    在POJ 1696这个编程题目中,很可能需要解决与极角排序相关的问题。POJ(Problem Online Judge)是一个在线的编程竞赛平台,它提供了许多编程题目供参赛者解决,以提升编程能力和算法理解。 描述中提到的“叉积+深搜...

    JAVA中的优先队列与堆(POJ 2442)

    在"POJ 2442"这个编程问题中,我们可能需要利用优先队列解决一些排序或者寻找最优解的问题。例如,假设题目要求找到一系列任务的最早完成时间,其中每个任务都有一个开始时间和结束时间,我们可以使用优先队列来存储...

    POJ算法题目分类

    * 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大匹配的算法,如 poj3041、poj3020。 * 最大流的增广路算法:最大流的增广路算法是指计算...

    poj:在poj.org上做的一些算法题

    【标题】"poj.org算法题解集合"是关于在poj.org平台上解决的各种算法问题的集合,这个资源主要是为了帮助编程爱好者和学习者提升算法技能。poj.org是一个著名的在线编程竞赛平台,它提供了丰富的算法题目供用户实践...

    poj训练计划.doc

    - 堆:如二叉堆,用于实现优先队列,如`poj3253`。 - 树:如二叉树和AVL树,用于存储和检索有序数据,如`poj2513`。 - **简单搜索** - 深度优先搜索:如`poj2488, poj3083`。 - 广度优先搜索:如`poj3278, poj...

Global site tag (gtag.js) - Google Analytics