问题描述
多米诺骨牌游戏规则非常简单,将骨牌按一定间距的尺寸排成单行,或分行排成一片。推倒第一张骨牌,其余发生连锁反应依次倒下,或形成一条长龙,或形成一幅图案。
小 A 觉得多米诺骨牌超级没意思,所以他想了点小花招。
小 A 将 n 个多米诺骨牌放在一条线上,每一块都垂直竖立。他同时将一些骨牌向左或向右推倒。注意:不会出现连续向左或者向右推的情况。 每过一秒,被推向左边或右边的骨牌会将左边或右边的相邻骨牌推倒。当一个骨牌,其左边倒向它的骨牌数目与其右边倒向它的骨牌数目相等时,由于力的平衡,该骨牌将依然保持竖立。
给定小 A 最初推骨牌的方向,求出最后依然保持竖立的骨牌数目和位置。
输入格式
输入数据第一行包括一个整数 n(1≤n≤3000),表示这一行多米诺骨牌的数目。下一行包括一个长度为 n 的字符串,字符串的第 i 个字符意义如下:
“L”,第 i 个字符将要被向左推。
“R”,第 i 个字符将要被向右推。
“.”,第 i 个字符不会被推。
输出格式
首先输出保持竖立的骨牌数目。如果保持竖立的骨牌数目不为 0,下一行输出保持竖立的骨牌的位置,骨牌位置从 1 到 n。
每两个数之间用一个空格隔开,注意最后一个数后面没有空格。
输入样例
14
.L.R...LR..L..
5
R....
1
.
输出样例
4
3 6 13 14
0
1
1
解题思路
为了解决这个问题,我们首先要了解骨牌在什么情况下会树立
- 骨牌左侧向左倒或右侧向右倒,则骨牌树立(题目条件:不会出现连续向左或者向右推的情况)
- 骨牌左侧向右倒,右侧向左倒,且左右之间骨牌数为奇数,中间骨牌树立 找到骨牌,判断左右两端的状态,若满足上述条件,则树立
具体步骤
1.寻找骨牌区间
采用双指针来找寻'.'
(骨牌区间)
i
代表骨牌开始的下标,j
表示骨牌结束的下一个牌
2.判断是否树立
利用left
记录data[i-1]
利用right
记录data[j]
注意: 如果骨牌在边界,我们需要将不在范围内的data[i]与data[j]赋值为'.'
以便之后进行判断。
char left=(i-1>=0)?data[i-1]:'.';
char right=(j<num)?data[j]:'.';
通过比较left
、right
与'L'
,'R'
,即可判断骨牌是否树立。(等于不好判断,我们可以利用不等于进行简化)
补充:
std::to_string(data)
十进制数字转为字符串
算法实现
#include <iostream>
#include <string>
#include<string.h>
#include<vector>
std::string solution(int num, std::string data) {
// Please write your code here
std::vector<int> result;
int i=0;
while(i<num){
if(data[i]=='.'){
int j=i;
while(data[j]=='.'&&j<num)j++;//查找骨牌区间
char left=(i-1>=0)?data[i-1]:'.';//查看骨牌区间左部
char right=(j<num)?data[j]:'.';//查看骨牌区间右部
if(left=='R'&&right=='L'&&(j-i)%2==1){
result.push_back(i+(j-i)/2+1);//骨牌左侧向右倒,右侧向左倒,且左右之间骨牌数为奇数,中间骨牌树立
}else if(left!='R'&&right!='L'){//骨牌左侧向左倒或右侧向右倒,则骨牌树立
for(int k=i;k<j;k++) result.push_back(k+1);
}
i=j;
} else i++;
}
std::string count;//输出
count=count+std::to_string(result.size())+':';
for(int i=0;i<result.size();i++)
{
count+=std::to_string(result[i])+',';
}
count=count.substr(0,count.length()-1);
return count;
}
int main() {
// You can add more test cases here
std::cout << (solution(14, ".L.R...LR..L..") == "4:3,6,13,14") << std::endl;
std::cout << (solution(5, "R....") == "0") << std::endl;
std::cout << (solution(1, ".") == "1:1") << std::endl;
return 0;
}