题目来源:洛谷

题目描述

有一个 1 ∗ n 的矩阵,有 n 个正整数。

现在给你一个可以盖住连续的 k 的数的木板。

一开始木板盖住了矩阵的第 1 ∼ k 个数,每次将木板向右移动一个单位,直到右端与第 n 个数重合。

每次移动前输出被覆盖住的最大的数是多少。

输入格式

第一行两个数,n,k,表示共有 n 个数,木板可以盖住 k 个数。

第二行 n 个数,表示矩阵中的元素。

输出格式

共 n − k + 1 行,每行一个正整数。

第 i 行表示第 i ∼ i + k − 1 个数中最大值是多少。

输入输出样例

输入 #1
5 3
1 5 3 4 2
输出 #1
5
5
4

数据范围:

对于 20% 的数据保证:1 ≤ n ≤ 1e3,1 ≤ k ≤ n

对于 50% 的数据保证:1 ≤ n ≤ 1e4,1 ≤ k ≤ n

对于 100% 的数据保证:1 ≤ n ≤ 2 ∗ 1e6,1 ≤ k ≤ n

矩阵中元素大小不超过 1e4

思路:

题目意思:求i-k+1~i之间的最大值

最大值可以用STL里的priority_queue来存储,队内元素从大到小,当队头元素的位置不在i-k+1~i的时候(模板盖不到)就删除(因为他已经没有利用价值了)

那么我们怎么知道队头元素在不在木板内呢?可以将队列元素的类型定义为结构体,存储元素值和编号

定义:

struct node{
	int num; //元素值
	int id; //元素编号
	bool operator<(const node&a) const
	{
		return a.num>num;
     //这样的话就按照元素值从小到大排序
	}
}e;
priority_queue<node> q;

在每次输出前判断一下队头是否符合要求,将不符合要求的删除,就行了

code:

#include<bits/stdc++.h>
using namespace std;
int n,k;
struct node{
	int num;
	int id;
	bool operator<(const node&a) const
	{
		return num<a.num;
	}
}e;
priority_queue<node> q;
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++)
	{
		int a;
		scanf("%d",&a);
		e.num=a; e.id=i;
		q.push(e); //将类型为node的e推进去 
		if (i>=k) //可以输出 
		{
			while (q.top().id<i-k+1) q.pop(); //其实改成if语句也行,因为每次最多删除一个队头 
			printf("%d\n",q.top().num); //输出队头的元素值 
		}
	}
	return 0;
}