WHYZOJ-#47. 滑行的窗口(单调队列)

【题目描述】:

给定一个长度为n的数列a,再给定一个长度为k的滑动窗口,从第一个数字开始依次框定k个数字,求每次框定的数字中的最大值和最小值,依次输出所有的这些值。下面有一个例子数组是 [1 3 1 3 5 6 7] , k 是3:

       窗口位置              窗口中的最小值   窗口中的最大值
[1  3  -1] -3  5  3  6  7            -1            3
 1 [3  -1  -3] 5  3  6  7            -3            3
 1  3 [-1  -3  5] 3  6  7            -3            5
 1  3  -1 [-3  5  3] 6  7            -3            5
 1  3  -1  -3 [5  3  6] 7             3            6
 1  3  -1  -3  5 [3  6  7]            3            7

【输入描述】:

第一行包含两个整数 n 和 k ,分别表示数组的长度和滑动窗口长度。

第二行n个整数,表示数列元素的值。

【输出描述】:

第一行从左到右窗口看到的最小值。

第二行从左到右窗口看到的最大值。

【样例输入】:

8 3
1 3 -1 -3 5 3 6 7

【样例输出】:

-1 -3 -3 -3 3 3
3 3 5 5 6 7

【时间限制、数据范围及描述】:

时间:1s 空间:64M

30%:n<=100 k<=20

60%:n<=5000 k<=20

100%:n<=10^6,每个元素不操过int类型

需要读入输出优化

二十分钟敲完……手速还算可以:( 不过今天也就这样了;(

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=1000005;
 5 int n,m;
 6 int a[MAX];
 7 struct Que{
 8     int na;
 9     int sco;
10 }q[MAX];
11 inline int read(){
12     int an=0,x=1;char c=getchar();
13     while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();}
14     while (c>='0' && c<='9') {an=an*10+c-'0';c=getchar();}
15     return an*x;
16 }
17 void getmin(){
18     int i,j;
19     int head=1,tail=0;
20     for (i=1;i<=n;i++){
21         while (head<=tail && i-q[head].na>=m) head++;
22         while (head<=tail && a[i]<q[tail].sco) tail--;
23         q[++tail].sco=a[i];q[tail].na=i;
24         if (i>=m){
25             printf("%d ",q[head].sco);
26         }
27     }
28     printf("\n");
29 }
30 void getmax(){
31     int i,j;
32     int head=1,tail=0;
33     for (i=1;i<=n;i++){
34         while (head<=tail && i-q[head].na>=m) head++;
35         while (head<=tail && a[i]>q[tail].sco) tail--;
36         q[++tail].sco=a[i];q[tail].na=i;
37         if (i>=m){
38             printf("%d ",q[head].sco);
39         }
40     }
41     printf("\n");
42 }
43 int main(){
44     freopen ("window.in","r",stdin);
45     freopen ("window.out","w",stdout);
46     int i,j;
47     n=read();m=read();
48     for (i=1;i<=n;i++){
49         a[i]=read();
50     }
51     getmin();
52     getmax();
53     return 0;
54 }

 

转载于:https://www.cnblogs.com/keximeiruguo/p/7555058.html

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值