题目来源:洛谷
题目描述
有一个 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;
}