算法训练营0:栈排序,直方图最大面积,最大红矩形

栈排序

问题描述

给定一个序列 A,请你将它升序排序。

输入格式

第一行一个正整数 n,表示序列长度。

第二行 n 个用空格隔开的非负整数,描述这个序列。

输出格式

n 行,每行一个非负整数,表示排序后的序列。

样例输入

4
1 3 2 10

样例输出

1
2
3
10

数据范围
保证 n<=1000,保证序列中的数不超过 32767

栈排序

#include<iostream>
#include<stack>
#include<vector>
using namespace std;

//myStack:输入栈,栈中的所有元素即是待排序的元素

//返回值:输出栈,即排序后的序列,满足从栈底至栈顶为升序
template <typename T>
stack<T> sorting(stack<T> myStack)
{
	stack<T> result;

	if (myStack.empty())
		return result;
	T tmp = myStack.top();
	myStack.pop();
	result.push(tmp);

	//(!result.empty() && tmp < result.top() 最后一个元素 可能小于 其他元素值
	while (!myStack.empty() || (!result.empty() && tmp < result.top()))
		
	if (result.empty() || tmp >= result.top())
	{
		result.push(tmp);
		tmp = myStack.top();
		myStack.pop();
	}
	else
	{
		myStack.push(result.top());
		result.pop();		
	}		
	result.push(tmp);

	return result;
}

int main()
{
	stack<int> R;    //乱序的堆栈,将从该堆栈一直pop元素到堆栈S 
	int nums;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> nums;
		R.push(nums);
	}

	stack<int> result = sorting(R);
	vector<int> answer;

	while (!result.empty())
	{
		answer.push_back(result.top());  //将堆栈里的内容从尾部一个一个添加到vector 
		result.pop();
	}
	//反向迭代器 ,因为我们需要输出升序,就需要将容器逆序输出 
	for (vector<int>::reverse_iterator i = answer.rbegin(); i != answer.rend(); ++i)
	{
		cout << *i << endl;
	}	
	return 0;
}

直方图最大面积

问题描述

有一个直方图,横轴长度为 n,第 i 列的高度为 h[i]。

请你求出在这个直方图中面积最大的子矩阵。

输入格式
第一行一个正整数 n。

第二行 n 个用空格隔开的非负整数,依次描述 h[1],h[2],…,h[n]。

输出格式
输出一行一个数,表示最大面积。

样例输入

5

2 3 3 3 2

样例输出

10

数据范围
对于 30% 的测试点,保证 n<=4。

对于 70% 的测试点,保证 n<=1000。

对于所有测试点,保证 n<=50000。

保证所有 h[i] 不超过 32767。

    C  -hints

 

 

代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 // n:意义如题
 5 // height:高度数组,height[i]表示第i列的高度(下标从1开始),数组大小为n+2,其中height[0]和height[n+1]都为0
 6 // 返回值:题目所求答案,即最大面积
 7 int getAnswer(int n, int *height) 
 8 {
 9     int ans = 0;
10     stack<int> myStack;
11     
12     myStack.push(0);
13     for(int i = 1; i < n + 2; i++)
14     {
15         while(!myStack.empty())
16         {
17             if(height[i] >= height[myStack.top()])
18             {
19                 myStack.push(i);                
20                 break;
21             }
22             else
23             {
24                 int nowlocal = myStack.top();            
25                 myStack.pop();
26                 int tmpans = height[nowlocal]*(i-myStack.top()-1);
27                 if(tmpans > ans)
28                     ans = tmpans;                
29             }            
30         }
31     }
32     return ans;
33 }
34 
35 int main() 
36 {
37     int n;
38     cin >> n;
39     
40     int* height = new int[n + 2]();
41     
42     for (int i = 1; i <= n; ++i)
43         cin >> height[i];
44     
45     cout << getAnswer(n, height) << endl;
46     
47     delete[] height;
48     return 0;
49 }
View Code

 

可参考 https://www.cnblogs.com/linkstar/p/6139668.html

最大红矩形

时间限制:4 sec

空间限制:256 MB

问题描述
有一个 n*m 的棋盘,棋盘上的每个点都是红的或绿的。

你需要找出一个面积最大的矩形区域,使得其中没有绿的格子。

输入格式
第一行 2 个正整数 n,m,描述棋盘尺寸。

接下来 n 行描述这个棋盘,每行 m 个字符,每个字符为 . 或 X,其中 . 表示这个位置是红色的,X 表示这个位置是绿色的。

输出格式
一行一个整数,表示最大面积。

样例输入

4 5
.....
XXXXX
.X...
.....

样例输出

6

样例解释
以第 3 行第 3 列的方格为左上角,第 4 行第 5 列的方格为右下角的矩形区域是全红的矩形中面积最大的。

数据范围
对于 30% 的数据,n,m<=100;

对于 60% 的数据,n,m<=400;

对于 85% 的数据,n,m<=1,000;

对于 100% 的数据,n,m<=1,500。

第一步先将点和X化为数字1和0,然后每列从上到下依次相加,X则不相加,例如示例

转换后

1 1 1 1 1
0 0 0 0 0
1 0 1 1 1
1 1 1 1 1

相加后

1 1 1 1 1
0 0 0 0 0
1 0 1 1 1
2 1 2 2 2

接着对每一层进行遍历,并利用直方图最大面积的方法计算。

posted on 2019-09-07 22:40  flysong  阅读(262)  评论(0编辑  收藏  举报

导航