大致题意:
给出一列共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;
}
分享到:
相关推荐
我的博客链接:http://blog.csdn.net/CABI_ZGX
标题“堆排序练习:POJ 2388”指的是一个关于使用堆排序算法解决编程竞赛问题的实践案例。在编程竞赛中,如POJ(Programming Online Judge)平台上的问题2388,参赛者经常需要高效地解决排序问题,而堆排序作为一种...
- 堆优化的Dijkstra算法 - **题目示例**: - POJ 1860、POJ 3259:利用Dijkstra算法解决最短路径问题。 - POJ 1062、POJ 2253:涉及Bellman-Ford算法的应用场景。 - POJ 1125、POJ 2240:Floyd算法的典型实例。 ...
在数组中找出第K大的元素,可以采用多种方法实现,如快速选择、堆排序或优先队列。这里我们可以利用已排序的数组,通过一次遍历找到第K个元素。也可以采用迭代或者递归的方式,逐步缩小查找范围。 在解决POJ2092...
- POJ 1753: 排序相关问题 - POJ 2965: 排序应用实例 - **搜索**:包括深度优先搜索(DFS)、广度优先搜索(BFS)等。 - **示例题目**: - POJ 1328: DFS的应用 - POJ 2109: BFS的应用 - POJ 2586: 搜索技巧展示 -...
在题目"poj2823"中,我们看到它被应用于寻找区域间的最大值和最小值。线段树通常用于解决动态规划问题,特别是在数组或序列上执行范围查询和修改时,能提供O(log n)的时间复杂度。 线段树的基本概念: 线段树是由一...
- (poj1094):适用于有向无环图(DAG)的一种排序方式,表示事件发生的顺序。 5. **网络流**: - (poj3041, poj3020):探讨如何在网络中找到最大流的问题,常用算法包括福特-福克森算法等。 6. **匹配算法**: ...
- **定义**: 包括快速排序、归并排序和堆排序等,用于将数据按照一定顺序排列。 - **应用场景**: 应用于几乎所有需要对数据进行排序的场景。 - **示例题目**: - poj2388: 涉及排序问题,可用快速排序或归并排序解决...
这是来自poj的一道关于单调队列的题目。分为max_qu和min_qu两部分来做。
这是西北工业大学的POJ试题的答案,欢迎下载!
这个练习题目,"POJ 2388",显然是通过编程实现直接插入排序来解决一个特定的问题。在这个问题中,我们需要理解直接插入排序的机制,并能用Java语言编写出高效的代码。 直接插入排序的基本步骤如下: 1. 从第二个...
* 堆:例如 poj2513。 * trie 树:例如 poj2513。 4. 简单搜索: * 深度优先搜索:例如 poj2488、poj3083、poj3009、poj1321、poj2251。 * 广度优先搜索:例如 poj3278、poj1426、poj3126、poj3087、poj3414。 ...
POJ 2703:选择出行方式 **题目概述**: 本题目旨在通过编程的方式解决一个实际问题——选择最佳出行方式(步行或骑自行车)。题目给出了一种算法来决定在不同条件下应该采取哪种出行方式。 **代码解析**: - **...
网上整理的一些poj刷题指南。 poj地址:http://poj.org
在POJ 1696这个编程题目中,很可能需要解决与极角排序相关的问题。POJ(Problem Online Judge)是一个在线的编程竞赛平台,它提供了许多编程题目供参赛者解决,以提升编程能力和算法理解。 描述中提到的“叉积+深搜...
在"POJ 2442"这个编程问题中,我们可能需要利用优先队列解决一些排序或者寻找最优解的问题。例如,假设题目要求找到一系列任务的最早完成时间,其中每个任务都有一个开始时间和结束时间,我们可以使用优先队列来存储...
* 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大匹配的算法,如 poj3041、poj3020。 * 最大流的增广路算法:最大流的增广路算法是指计算...
【标题】"poj.org算法题解集合"是关于在poj.org平台上解决的各种算法问题的集合,这个资源主要是为了帮助编程爱好者和学习者提升算法技能。poj.org是一个著名的在线编程竞赛平台,它提供了丰富的算法题目供用户实践...
- 堆:如二叉堆,用于实现优先队列,如`poj3253`。 - 树:如二叉树和AVL树,用于存储和检索有序数据,如`poj2513`。 - **简单搜索** - 深度优先搜索:如`poj2488, poj3083`。 - 广度优先搜索:如`poj3278, poj...