分值:100
题目描述
向一个空栈压入正整数,每当压入一个整数时,执行以下规则(设: 栈顶至栈底整数依次编号为n1、n2...nx, n1为最新压入的整数)。
- 如果
n1 = n2,则n1、n2全部出栈,压入新数据m(m = 2 * n1)。 - 如果
n1 = n2 + ... + ny(y的范围为[3,x]),则n1、n2...ny全部出栈,压入新数据m(m = 2 * n1)。 - 如果上述规则都不满足,则不做操作。
如: 依次向栈压入6、1、2、3,当压入2时,栈顶至栈底依次为[2, 1, 6];当压入3时,3 = 2 + 1,3、2、1全部出栈,重新入栈整数6,此时栈顶至栈底依次为[6, 6];6 = 6,两个6全部出栈,压入12,最终栈中只剩个元素12。
向栈中输入一串数字,请输出应用此规则后栈中最终存留的数字。
输入描述:
使用单个空格隔开的正整数的字符串,如5 6 7 8,左边的数字先入栈。
输出描述:
最终栈中存留的元素值,元素值使用空格隔开,如8 7 6 5,栈顶数字在左边。
示例1
输入:
5 10 20 50 85 1
输出:
1 170
解释:
5 + 10 + 20 + 50 = 85,输入 85 时,5、10、20、50、85 全部出栈,入栈 170,最终依次出栈的数字为 1 和 170。
示例2
输入:
6 7 8 13 9
输出:
9 13 8 7 6
示例2
输入:
1 2 5 7 9 1 2 2
输出:
4 1 9 14 1
Tips:
- 输入的正整数个数为
x,1<=x<=1000 0 < n1, n2...ny < 1e5
思路
- 结合 1 跟 2 两条信息,可以等价于如果当前要进栈的数字
num,如果跟后面连续k个数字之和相等的话,就把这些数字都出栈并且把2 * num入栈。 - 为了快速遍历当前栈里面的元素,本题可以使用数组来模拟栈的操作。
- 由于都是正整数,所以数字之和具有单调性。所以如果数据范围
x > 1e5的话,可以使用前缀和+二分查找进行优化。本题数据范围较小,可以直接使用两层for循环暴力模拟得出答案。
复杂度分析
- 时间复杂度: O(N2)O(N^2)O(N2),其中
N为数字个数。 - 空间复杂度: O(N)O(N)O(N),其中
N为数字个数。
AC 代码
C++ 版
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e3 + 5;
vector<int> split(string str, char point)
{
vector<int> res;
stringstream ss(str);
string token;
while (getline(ss, token, point))
{
// stoi 要求 C++ 11 以上
res.push_back(stoi(token.c_str()));
}
return res;
}
int main()
{
vector<int> s(MAX);
int pos = 0; // pos 表示栈顶下一个位置
string str;
getline(cin, str);
vector<int> seats = split(str, ' ');
for (auto num : seats)
{
s[pos] = num;
int cur = 0;
// 计算 pos 之前的数字之和,如果恰好有连续的数字之和等于 num 的话,就合并然后入栈
for (int i = pos - 1; i >= 0 && cur < num; i--)
{
cur += s[i];
if (cur == num)
{
s[i] = num * 2;
pos = i;
break;
}
}
pos++;
}
for (int i = pos - 1; i >= 0; i--)
{
cout << s[i] << " ";
}
return 0;
}
JAVA 版
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int MAX = 1005;
int[] s = new int[MAX];
int pos = 0;
String str = scanner.nextLine();
String[] parts = str.split(" ");
int[] seats = new int[parts.length];
for (int i = 0; i < parts.length; i++) {
seats[i] = Integer.parseInt(parts[i]);
}
for (int num : seats) {
s[pos] = num;
int cur = 0;
for (int i = pos - 1; i >= 0 && cur < num; i--) {
cur += s[i];
if (cur == num) {
s[i] = num * 2;
pos = i;
break;
}
}
pos++;
}
for (int i = pos - 1; i >= 0; i--) {
System.out.print(s[i] + " ");
}
}
}
Python 版
def split(string, point):
return [int(x) for x in string.split(point)]
MAX = 1005
s = [0] * MAX
pos = 0
str = input()
seats = split(str, ' ')
for num in seats:
s[pos] = num
cur = 0
for i in range(pos - 1, -1, -1):
if cur < num:
cur += s[i]
if cur == num:
s[i] = num * 2
pos = i
break
pos += 1
for i in range(pos - 1, -1, -1):
print(s[i], end=' ')
1449

被折叠的 条评论
为什么被折叠?



