问题描述
小S玩起了多米诺骨牌,他排列了一行骨牌,并可能将某些骨牌向左或向右推倒。随着骨牌连锁反应的进行,一些骨牌可能因为左右两侧受力平衡而保持竖立。现在小S想要知道在所有动作完成后,哪些骨牌保持竖立。
给定一个表示骨牌初始状态的字符串,其中:
- "L" 表示该位置的骨牌将向左倒。
- "R" 表示该位置的骨牌将向右倒。
- "." 表示该位置的骨牌初始时保持竖立。
模拟整个骨牌倒下的过程,求出最终仍然保持竖立的骨牌的数目和位置。
测试样例
样例1:
输入:
num = 14,data = ".L.R...LR..L.."输出:'4:3,6,13,14'
样例2:
输入:
num = 5,data = "R...."输出:'0'
样例3:
输入:
num = 1,data = "."输出:'1:1'
思路
这个问题要求我们模拟多米诺骨牌的倒下过程,并找出最终仍然保持竖立的骨牌。我们可以通过以下步骤来解决这个问题:
- 初始化状态数组:首先,我们需要一个数组来记录每个骨牌的状态。初始时,所有骨牌都是竖立的,所以我们可以初始化一个长度等于骨牌数量的数组,所有元素都设为0。
- 模拟向左倒的骨牌:从左到右遍历字符串,如果遇到一个'L',我们就开始向左倒。这意味着当前骨牌和它右边的骨牌都会受到影响。我们将当前骨牌的状态设为1,然后继续向右检查,直到遇到'R'或字符串结束。每遇到一个'L',我们就把受影响的骨牌的状态加1。
- 模拟向右倒的骨牌:接下来,我们从右到左遍历字符串,模拟向右倒的过程。如果遇到一个'R',我们就开始向右倒。这意味着当前骨牌和它左边的骨牌都会受到影响。我们将当前骨牌的状态设为-1,然后继续向左检查,直到遇到'L'或字符串开始。每遇到一个'R',我们就把受影响的骨牌的状态减1。
- 计算保持竖立的骨牌:在完成上述两个步骤后,状态数组中的每个元素就代表了相应骨牌的净倒下方向。值为0的元素表示该骨牌保持竖立。我们统计状态数组中值为0的元素数量,这就是保持竖立的骨牌的数量。
- 输出结果:最后,我们将保持竖立的骨牌的数量和它们的位置输出。如果没有任何骨牌保持竖立,我们只输出数量0。
代码
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
std::string solution(int num, std::string data) {
vector<int> state(num, 0);
int start = 0;
int len = 0;
for(int i = 0; i < num; i ++){
if(data[i] == 'R'){
start = 1;
}else if(start && data[i] != 'L'){
start++;
}else{
start = 0;
}
state[i] += start;
}
start = 0;
len = 0;
for(int i = num - 1; i >= 0; i--){
if(data[i] == 'L'){
start = -1;
}else if(start && data[i] != 'R'){
start--;
}else{
start = 0;
}
state[i] += start;
}
int ans = count(state.begin(), state.end(), 0);
if(ans == 0) return "0";
string res = to_string(ans) + ':';
for(int i = 0; i < num;i++){
if(state[i] == 0){
res += to_string(i+1) + ',';
}
}
res.pop_back();
return res;
}