POJ 2823 Sliding Window

 

题意:n个数,用长度为k的框从左往右逐个框进k个数,输出每次框进的数的最大数和最小数。

分析:裸的单调队列。此题输入输出量很大,用scanf和printf,C++编译器。用G++会TLE。不过用输入输出加速外挂会提高速度。

Source Code:

#include<iostream>
#include<cstdio>
using namespace std;

const int maxn=1000010;
struct Node{
	int val,idx;
}que[maxn];
int ans[maxn],num[maxn];

void scan_d(int &num)//输入外挂
{
    char in;
    bool neg=false;
    while(((in=getchar()) > '9' || in<'0') && in!='-') ;
    if(in=='-'){
        neg=true;
        while((in=getchar()) >'9' || in<'0');
    }
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
    if(neg) num=0-num;
}

void out(int a) //输出外挂 
{  
    if(a < 0) {putchar('-'); a = -a;}  
    if(a >= 10)out(a / 10);  
    putchar(a % 10 + '0');  
}  


int main()
{
	int i,j,k,head,tail,n;
	scanf("%d %d",&n,&k);
	for(i=0;i<n;i++)
		scan_d(num[i]);
	head=tail=0;
	for(i=0;i<n;i++){
		if(head<tail&&que[head].idx<=i-k) head++;
		while(head<tail&&que[tail-1].val>=num[i]) tail--;
		que[tail].idx=i;
		que[tail++].val=num[i];
		ans[i]=que[head].val;
	}
	for(i=k-1;i<n-1;i++){
		out(ans[i]);
	    putchar(' ');
	}
	out(ans[i]);
	putchar('\n');
	head=tail=0;
	for(i=0;i<n;i++){
		if(head<tail&&que[head].idx<=i-k) head++;
		while(head<tail&&que[tail-1].val<=num[i]) tail--;
		que[tail].val=num[i];
		que[tail++].idx=i;
		ans[i]=que[head].val;
	}
	for(i=k-1;i<n-1;i++){
		out(ans[i]);
		putchar(' ');
	}
	out(ans[i]);
	putchar('\n');
	return 0;
}


 

你可能感兴趣的:(POJ 2823 Sliding Window)