1.
题目描述:
薯队长写了一篇笔记草稿,请你帮忙输出最后内容。
①.输入字符包括英文字符,"(" , ")" 和 "<"。
②.英文字符表示笔记内容。
③. ( ) 之间表示注释内容,任何字符都无效。 括号保证成对出现。
④. "<" 表示退格, 删去前面一个笔记内容字符。 括号不受 "<" 影响 。
输入
输入一行字符串。长度 <= 10000.
输出
输出一行字符串,表示最终的笔记内容。
样例输入
a<<b((c)<)
样例输出
b
提示
a退格删除掉了, 括号里面的c不要, 最后一个< 无效
两个解决方案:
第一个使用栈(没有提交运行过,仅测试过部分示例):
#include<iostream>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
void str_print(string str) {
stack<char>s;
for (int i = 0; i < str.length(); i++) {
//s为空
if (s.empty()) {
bool flag = false;
while (!flag && i < str.length()) {
if (str[i] != '<') {
flag = true;
s.push(str[i]);
i++;
}
else {
i++;
}
}
}
if (i >= str.length())break;
//s非空
if (s.top() != '(') {
if (str[i] != '<') {
s.push(str[i]);
}
else {
s.pop();
}
}
else {
if (str[i] == '(') {
s.push(str[i]);
}
else if (str[i] == ')') {
s.pop();
}
}
}
vector<char>res;
while (!s.empty()) {
char t = s.top();
res.push_back(t);
s.pop();
}
for (int i = res.size() - 1; i >= 0; i--) {
cout << res[i];
}
}
int main() {
string str;
cin >> str;
str_print(str);
return 0;
}
第二个不适用栈:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string input_str;
cin >> input_str;
vector<char> content;
int curr_kh = 0;
int str_len = input_str.length();
int i;
for (i = 0; i < str_len; ++i)
{
if (input_str[i] == '(')
{
curr_kh += 1;
}
else if (input_str[i] == ')')
{
curr_kh -= 1;
}
else if (input_str[i] == '<')
{
if (curr_kh == 0)
{
if (!content.empty())
content.pop_back();
}
}
else
{
if (curr_kh == 0)
{
content.push_back(input_str[i]);
}
}
}
for (i = 0; i < (int)content.size(); ++i)
{
cout << content[i];
}
cout << endl;
return 0;
}
2.
题目描述:
薯队长最近在玩一个迷宫探索类游戏,迷宫是一个N*N的矩阵形状,其中会有一些障碍物禁止通过。这个迷宫还有一个特殊的设计,它的左右边界以及上下边界是连通的,比如在(2,n)的位置继续往右走一格可以到(2,1), 在(1,2)的位置继续往上走一格可以到(n,2)。请问薯队长从起点位置S,最少走多少格才能到达迷宫的出口位置E。
输入
第一行正整数 N。 接下来 N 行 字符串。
’.’表示可以通过,’#’表示障碍物, ’S’表示起点(有且仅有一个),’E’表示出口(有且仅有一个)。
对于50%的数据
0 < N < 10
对于100%的数据
0 < N < 10^3
输出
输出一个整数。表示从S到E最短路径的长度, 无法到达则输出 -1
样例输入
5
.#…
..#S.
.E###
…..
…..
样例输出
4
提示
向右来到(2,5)
向右来到(2,1)
向下来到(3,1)
向右来到(3,2)
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
void bfs(vector<vector<char>> matrix) {
//找到起点和出口
vector<int>source(3, 0);
vector<int>exit(3, 0);
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix.size(); j++) {
if (matrix[i][j] == 'S') {
source[0] = i;
source[1] = j;
}
if (matrix[i][j] == 'E') {
exit[0] = i;
exit[1] = j;
exit[2] = -1;
}
}
}
//bfs
queue<vector<int>>s;
s.push(source);
vector<bool>visit_array(matrix.size(), false);
vector<vector<bool>>visit(matrix.size(), visit_array);
visit[source[0]][source[1]] = true;
while (!s.empty()) {
vector<int>temp = s.front();
s.pop();
int step = ++temp[2];
//上
if (!visit[(temp[0] - 1 + matrix.size()) % matrix.size()][temp[1]] && matrix[(temp[0] - 1 + matrix.size()) % matrix.size()][temp[1]] == '.') {
vector<int>t;
t.push_back((temp[0] - 1 + matrix.size()) % matrix.size());
t.push_back(temp[1]);
t.push_back(step);
s.push(t);
visit[(temp[0] - 1 + matrix.size()) % matrix.size()][temp[1]] = true;
}
else if (matrix[(temp[0] - 1 + matrix.size()) % matrix.size()][temp[1]] == 'E') {
cout << step << endl;
return;
}
//下
if (!visit[(temp[0] + 1) % matrix.size()][temp[1]] && matrix[(temp[0] + 1) % matrix.size()][temp[1]] == '.') {
vector<int>t;
t.push_back((temp[0] + 1) % matrix.size());
t.push_back(temp[1]);
t.push_back(step);
s.push(t);
visit[(temp[0] + 1) % matrix.size()][temp[1]] = true;
}
else if (matrix[(temp[0] + 1) % matrix.size()][temp[1]] == 'E') {
cout << step << endl;
return;
}
//左
if (!visit[temp[0]][(temp[1] - 1 + matrix.size()) % matrix.size()] && matrix[temp[0]][(temp[1] - 1 + matrix.size()) % matrix.size()] == '.') {
vector<int>t;
t.push_back(temp[0]);
t.push_back((temp[1] - 1 + matrix.size()) % matrix.size());
t.push_back(step);
s.push(t);
visit[temp[0]][(temp[1] - 1 + matrix.size()) % matrix.size()] = true;
}
else if (matrix[temp[0]][(temp[1] - 1 + matrix.size()) % matrix.size()] == 'E') {
cout << step << endl;
return;
}
//右
if (!visit[temp[0]][(temp[1] + 1) % matrix.size()] && matrix[temp[0]][(temp[1] + 1) % matrix.size()] == '.') {
vector<int>t;
t.push_back(temp[0]);
t.push_back((temp[1] + 1) % matrix.size());
t.push_back(step);
s.push(t);
visit[temp[0]][(temp[1] + 1) % matrix.size()] = true;
}
else if (matrix[temp[0]][(temp[1] + 1) % matrix.size()] == 'E') {
cout << step << endl;
return;
}
}
cout << exit[2] << endl;
}
int main() {
int N = 0;
cin >> N;
vector<vector<char>>char_matrix;
for (int i = 0; i < N; i++) {
vector<char>char_array;
for (int j = 0; j < N; j++) {
char temp;
cin >> temp;
char_array.push_back(temp);
}
char_matrix.push_back(char_array);
}
bfs(char_matrix);
return 0;
}
3.
题目描述:
在游戏中,击败魔物后,薯队长获得了N件宝物,接下来得把这些宝物卖给宝物回收员来赚点小钱。这个回收员有个坏毛病,每次卖给他一件宝物后,之后他就看不上比这件宝物差的宝物了。在这个世界中,衡量宝物的好坏有两个维度,稀有度X和实用度H,回收员在回收一个宝物A后,下一个宝物的稀有度和实用度都不能低于宝物A。那么薯队长如何制定售卖顺序,才能卖给回收员宝物总个数最多。
输入
第一行一个正整数N。
接下来N行。每行两个整数分别表示X 和 H
X1 H1
X2 H2
…
XN HN
输入限制:
对于70%的数据:
0 < N < 10^4
0 < Xi < 10^6
0 < Hi < 10^6
对于100%的数据:
0 < N < 10^6
0 < Xi < 10^6
0 < Hi < 10^6
输出
一个整数,表示最多可以卖出的宝物数
样例输入
4
3 2
1 1
1 3
2 2
样例输出
3
提示
1. 将宝物2 (1,1)卖出
2. 将宝物4 (2,2)卖出
3. 将宝物1 (3,2)卖出
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//方法一:复杂度O(n2)
void LIS(vector<vector<int>>matrix) {
vector<int>d(matrix.size(), 0);
for (int i = 0; i < matrix.size(); i++) {
int maxlength = 0;
for (int j = i - 1; j >= 0; j--) {
if (matrix[j][1] <= matrix[i][1] && d[j] >= maxlength) {
maxlength = d[j];
}
}
d[i] = maxlength + 1;
}
int max = d[0];
for (int i = 1; i < d.size(); i++) {
if (d[i] > max) {
max = d[i];
}
}
cout << max << endl;
}
//方法二:复杂度O(nlogn)
void LIS_gready_binary(vector<vector<int>>matrix) {
if (matrix.size() == 0) {
cout << 0 << endl;
return;
}
vector<int>low;
//low[i]记录长度为i+1的LIS结尾元素最小值
//贪心:对于一个升序子序列,显然其结尾元素越小,越有利于在后面接其他的元素,也就越可能变得更长
low.push_back(matrix[0][1]);
for (int i = 1; i < matrix.size(); i++) {
if (matrix[i][1] >= low[low.size() - 1]) {
low.push_back(matrix[i][1]);
continue;
}
int l = 0, r = low.size() - 1;
//二分:找low数组第二列中第一个比matrix[i][1]大的数
while (l < r) {
int mid = (l + r) / 2;
if (low[mid] > matrix[i][1]) {
r = mid - 1;
}
else if (low[mid] < matrix[i][1]) {
l = mid + 1;
}
else {
l = mid;
}
}
low[l] = matrix[i][1];
}
cout << low.size() << endl;
}
int main() {
int N = 0;
cin >> N;
vector<vector<int>>matrix;
for (int i = 0; i < N; i++) {
vector<int>array;
int X = 0, H = 0;
cin >> X >> H;
array.push_back(X);
array.push_back(H);
matrix.push_back(array);
}
//第一步:根据第一列排序
sort(matrix.begin(), matrix.end());//默认按第一列排序
//第二步:对第二列找最长升序子序列
LIS(matrix);
LIS_gready_binary(matrix);
return 0;
}
最长上升子序列问题:
LeetCode:300、354
参考: