
荒岛求生
题目描述
有一个荒岛,只有左右两个港口,只有一座桥连接这两个港口,现在有一群人需要从两个港口逃生,有的人往右逃生,有的往左逃生,如果两个人相遇,则PK,体力值大的能够打赢体力值小的,体力值相同则同归于尽,赢的人才能继续往前逃生,并较少相应地体力。
输入描述
一行非0整数,用空格隔开,正数代表向右逃生,负数代表向左逃生。
输出描述
最终能够逃生的人数。
解题思路
题意是这样的:
体力值大的能够打赢体力值小的,体力值相同则同归于尽,赢的人才能继续往前逃生,并较少相应地体力。 正数代表向右逃生,负数代表向左逃生。
- 那就将正数加到一个集合里,负数加到一个集合里;
- 然后开始遍历取值;
- 体力值大的能够打赢体力值小的,并较少相应地体力;
- 体力值相同则同归于尽;
- 最后输出正数集合和负数集合的大小之和,最终能够逃生的人数;
效果展示
1、输入
10 20 -20 -5 10
2、输出
2
3、说明
正数集合:10 20 10
负数集合: -20 -5
20和-20同归于尽;
10和-5,抵消5体力值;
最终能够逃生的人数2人。
cpp
#include <iostream>
#include <vector>
#include <stack>
#include <cstdlib>
#include <sstream>
using namespace std;
int main() {
string input;
// 读取一行输入,包含非0整数,用空格隔开
getline(cin, input);
// 使用stringstream来处理输入的分割和转换
stringstream ss(input);
int num;
vector<int> nums;
// 将输入字符串转换为整数数组
while (ss >> num) {
nums.push_back(num);
}
// 正数栈
stack<int> positiveStack;
// 负数栈
stack<int> negativeStack;
for (int num : nums) {
if (num > 0) {
// 正数直接入栈
positiveStack.push(num);
} else {
// 负数代表向左逃生
int remainNum = abs(num);
while (!positiveStack.empty()) {
int positiveTop = positiveStack.top();
if (remainNum > positiveTop) {
// 消除当前的正数,还可以继续碰撞
remainNum -= positiveTop;
positiveStack.pop();
} else if (remainNum < positiveTop) {
// 消除当前的正数,然后修改top值
int modifyNum = positiveTop - remainNum;
positiveStack.pop();
positiveStack.push(modifyNum);
remainNum = 0;
break;
} else {
// 相等,同归于尽
positiveStack.pop();
remainNum = 0; // 被消除了
break;
}
}
// 如果还活着,负数入负数栈
if (remainNum > 0) {
negativeStack.push(-remainNum);
}
}
}
// 输出剩余的元素数量
cout << positiveStack.size() + negativeStack.size() << endl;
return 0;
}