栈,队列刷题

栈:

P3467 [POI2008]PLA-Postering

题目描述

All the buildings in the east district of Byteburg were built in accordance with the old arbitecture:

they stand next to each other with no spacing inbetween.

Together they form a very long chain of buildings of diverse height, extending from east to west.

The mayor of Byteburg, Byteasar, has decided to have the north face of the chain covered with posters.

Byteasar ponders over the minimum number of posters sufficient to cover the whole north face.

The posters have rectangular shape with vertical and horizontal sides.

They cannot overlap, but may touch each other, i.e. have common points on the sides.

Every poster has to entirely adjoin the walls of certain buildings and the whole surface of the north face has to be covered.

Task Write a programme that:

reads the description of buildings from the standard input, determines the minimum number of posters needed to entirely cover their north faces, writes out the outcome to the standard output.

Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长的,从东向西延伸的建筑物链(建筑物的高度不一).Byteburg市的市长Byteasar,决定将这个建筑物链的一侧用海报覆盖住.并且想用最少的海报数量,海报是矩形的.海报与海报之间不能重叠,但是可以相互挨着(即它们具有公共边),每一个海报都必须贴近墙并且建筑物链的整个一侧必须被覆盖(意思是:海报需要将一侧全部覆盖,并且不能超出建筑物链)

输入格式

The first line of the standard input contains one integer �n (1≤�≤250 0001≤n≤250 000), denoting the number of buildings the chain comprises of.

Each of the following �n lines contains two integers ��di​ and ��wi​ (1≤��,��≤1 000 000 0001≤di​,wi​≤1 000 000 000), separated by a single space, denoting respectively the length and height of the ��ℎith building in the row.

第一行为一个整数n(1≤n≤250000),表示有n个建筑,接下来n行中,第i行表示第i个建筑物的宽di与高wi(1≤di,wi≤1 000 000 000),中间由一个空格隔开

输出格式

The first and only line of the standard output should contain one integer, the minimum number of rectangular posters that suffice to cover the north faces of the buildings.

第一个为一个整数,表示最少需要几张海报.

输入输出样例

输入 #1复制

5
1 2
1 3
2 2
2 5
1 4

输出 #1复制

4

思路:

将数据入栈,如果有数据相同,就让它出栈。

代码:
 

#include<iostream>
using namespace std;
int main()
{
	long long int n, b, c, statck[200009], top = 0, num = 0;
	cin >> n;
	for(int i=0;i<n;i++)
	{
		cin >> b >> c;
		while (top > 0 &&c<= statck[top])
		{
			if(statck[top] == c) num++; --top;
		}
		statck[++top] = c;
	}
	cout << n - num;
}

P6704 [COCI2010-2011#7] GITARA

题目背景

Darko 有一个想象的外星朋友,他有十亿根手指。外星人快速拿起吉他,在网上找到一段简单的旋律并开始弹奏。

这个吉他像寻常一样有六根弦,令其用 11 到 66 表示。每根弦被分成 �P 段,令其用 11 到 �P 表示。

旋律是一串的音调,每一个音调都是由按下特定的一根弦上的一段而产生的(如按第 44 弦第 88 段)。如果在一根弦上同时按在几段上,产生的音调是段数最大的那一段所能产生的音调。

例:对于第 33 根弦,第 55 段已经被按,若你要弹出第 77 段对应音调,只需把按住第 77 段,而不需放开第 55 段,因为只有最后的一段才会影响该弦产生的音调(在这个例子中是第 77 段)。类似,如果现在你要弹出第 22 段对应音调,你必须把第 55 段和第 77 段都释放。

请你编写一个程序,计算外星人在弹出给定的旋律情况下,手指运动的最小次数。

题目描述

你有一个 6×�6×P 的矩阵 �A,初始状态皆为 00。

对于所有要求 (�,�)(i,j)

你需要满足要求:

  1. 此时 ��,�Ai,j​ 状态为 11。

  2. 对于 ��,�+�(�>0)Ai,j+k​(k>0) 状态为 00。

你在满足要求的情况下需要求状态转换最小次数。

输入格式

第一行包含两个正整数 �n ,�P。它们分别指旋律中音调的数量及每根弦的段数。

下面的 �n 行每行两个正整数 �i ,�j,分别表示能弹出对应音调的位置——弦号和段号,其为外星人弹奏的顺序。

输出格式

一个非负整数表示外星人手指运动次数最小值。

输入输出样例

输入 #1复制

5 15
2 8
2 10
2 12
2 10
2 5

输出 #1复制

7

输入 #2复制

7 15
1 5
2 3
2 5
2 7
2 4
1 5
1 3

输出 #2复制

9

说明/提示

样例 1 解释

所有的音调都是由第二根弦产生的。首先按顺序按 88 1010 1212 (�����=3count=3)。然后释放第 1212 段(�����=4count=4)。最后,按下第 55 段,释放第 88 1010 段 (�����=7count=7)。

样例 2 解释

对于每个操作,分别需要 11 11 11 11 33 00 22 次手指运动。

思路:
建立一个栈, statck[7][200009]。其中用数组来确定在那根弦。如果下一个数小于当前的数,则top--,num++。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,b, c, statck[7][200009], top[7] , num = 0;
int main()
{

	cin >> n >> m;
	for(int i=0;i<n;i++)
	{
		cin >> b >> c;
		while (top[b] > 0 && statck[b][top[b]]>c)
		{
			 num++; --top[b];
		}
		if (c == statck[b][top[b]]) continue;
		statck[b][++top[b]] = c;
		num++;
	}
	cout <<  num;
}

队列:

P2032 扫描

题目描述

有一个 1×�1×n 的矩阵,有 �n 个整数。

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

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

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

输入格式

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

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

输出格式

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

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

输入输出样例

输入 #1复制

5 3
1 5 3 4 2

输出 #1复制

5
5
4

思路:
如果队首到当前距离大于等于木板长度,那么队首出队。如果当前元素大于队末的元素,队尾出队

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 50;
int n, m, a[maxn], d[maxn];	
int h = 1, t = 0;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(i-d[h]>=m) h++;
        while(h<=t&&a[i]>=a[d[t]])
            t--;
        d[++t]=i;
        if(i>=m) cout<<a[d[h]]<<endl;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值