zoukankan      html  css  js  c++  java
  • POJ2823(单调队列方法解题)


    因为不太好复制,我就直接截图了,题目链接;题目大致的意思是:给一串数字,然后要你求出每k长度的连续子序列中的最大值以及最小值并输出;这题就是一个最简单的运用单调队列方法解题的例子。

    解题思路:通过单调队列,分别维护一个递增以及递减的数列以求得最小值和最大值(增减对应),其中用到了数组的游标删减,主要思想是通过一个f[]数组存储每次比较得出的最值,通过t[]数组存储游标(即变化的数组下标);

    代码:

    #include<cstdio>
    #include<cstdlib>
    #include<memory.h>
    #define Max_Size 1000000
    int t[Max_Size];
    int f[Max_Size];
    int num[Max_Size];
    
    int main()
    {
    	int n,k;
    	int i,j;
    	int min,max;
    	scanf("%d%d",&n,&k);
    	for(i=0;i<n;i++)
    	{
    		scanf("%d",&num[i]);
    	}
    	int tail=0,front=0;
    	for(i=0;i<n;i++)
    	{
    		while(front<tail&&f[tail-1]>num[i])tail--;                   //维护一个单调递增的序列,最后求得最小值; 
    		f[tail]=num[i];                                                   //每次这个数要么替换f[]中的数,要么直接加入,因此始终都是要加入到队列中,对其大小处理在后一个过程中的while()中处理; 
    		t[tail]=i;
    		tail++;
    		while(t[front]<=i-k)front++;
    		if(i>k-2)                                       //每三个数都要输出其中的最小值(即从第三个数开始); 
    		{
    			printf("%d%c",f[front],i==n-1?'
    ':' ');
    		}
    	}
    	tail=0;front=0;
    	memset(f,0,sizeof(f));
    	memset(t,0,sizeof(t)); 
    	for(i=0;i<n;i++)
    	{
    		while(front<tail&&f[tail-1]<num[i])tail--;
    		f[tail]=num[i];
    		t[tail]=i;
    		tail++;
    		while(t[front]<=i-k)front++;
    		if(i>k-2)
    		{
    			printf("%d%c",f[front],i==n-1?'
    ':' ');
    		}
    	}
    	return 0;
    }
    

    后续还有单调队列题目将会更新,并将链接附上;

  • 相关阅读:
    谈一谈循环的性能提升
    Web前端性能优化的9大问题
    随机获取一种颜色值的三种方法
    ES6还是ES2015?
    history.back(-1)和history.go(-1)的区别
    关于overflow-y:scroll ios设备不流畅的问题
    前端如何压缩图片
    【转】理解JavaScript之闭包
    关于如何给数字排序
    本地缓存localstorage使用
  • 原文地址:https://www.cnblogs.com/heihuifei/p/8065059.html
Copyright © 2011-2022 走看看