科大讯飞:争吵
发布于 2017-09-16 16:41 6078 次浏览 0 赞 来自 我要提问  

在线考试

编程题|20.0分1/3

争吵

时间限制:C/C++语言 2000MS;其他语言 4000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB

题目描述:

有 n 个人排成了一行队列,每个人都有一个站立的方向:面向左或面向右。由于这 n 个人中每个人都很讨厌其他的人,所以当两个人面对面站立时,他们会发生争吵,然后其中一个人就会被踢出队列,谁被踢出队列都是有可能的。

 

我们用字符 L 来表示一个面向左站立的人,用字符 R 来表示一个面向右站立的人,那么这个队列可以用一个字符串描述。比如 RLLR 就表示一个四个人的队列,其中第一个人和第二个人是面对面站立的。他们发生争吵后队列可能会变成 LLR,也可能变成 RLR;若变成 RLR,则第一个人与第二个人还会发生争吵,队列会进一步变成 LR 或者 RR。

 

若在某个时刻同时可能有很多的争吵会发生时,接下来只会发生其中的一个,且任意一个都是有可能发生的。

 

你想知道经过一系列的争吵后,这个队列最少会剩下多少人?

输入

第一行包含一个有字符 L 和 R 构成的字符串。

1 ≤字符串长度≤ 105

样例输入

LRRLRL

<div class="outputarea yangli ng-scope" ng-if="model.ques.questype==6 && model.ques.outputSample != null && model.ques.outputSample!=''" "="" style="box-sizing: border-box; margin: 0px; padding: 0px;">

样例输出

2


Hint

一种可能的变化情况是这样的:
LRRLRL -> LRLRL -> LRRL -> LRL -> LR


21 条回复
看了别人的思路,sysout(str.replaceAll("R.*L", "N").length())


2017-09-16 16:54
3
int nd = 0, r = 0, len = s.length();
for (int i = 0; i < len; ++ i) {
    if (s[i] == 'R') nd += 1;
    else {
        if (nd == 0) r += 1;
        else nd = 1;
       }
 }
 cout << (r+nd) << endl;


2017-09-16 17:04
1

找到第一个R和最后一个L,一减就知道去掉多少人了,就做出来这一道

2017-09-16 17:05
9

js一直90%,来个大佬说下哪里没考虑到

var str = read_line();
var arr = str.split('');
var len = arr.length;
var result = 0;
var re = /[R]+[L]+/g;
if (re.test(str)) {
	result++;
	str = str.replace(re, '');
}
result = result + str.length;
print(result);


2017-09-16 17:05
<?php
$handle = fopen ("php://stdin","r");
$s = fgets($handle);
$len = strlen($s);
$out = 0;
for($i=0;$i<$len;$i++){
	if($s[$i]=="L"){
        $out++;
    }else{
        $out++;
        break;
    }
}
if(strripos($s,"L",$out)){
    $last = strripos($s,"L",$out);
    $out += $len-1-$last;
}else{
    $out = $len;
}
echo $out;


2017-09-16 17:05

import java.util.Scanner;

public class TEST{

public static void main(String[] args){

Scanner sc = new Scanner(System.in);

String s = sc.nextLine();

    int index_L=s.indexOf('R');

int index_R=s.lastIndexOf('L');

System.out.println(index_L+s.length()-index_R);

        }

}


2017-09-16 17:07
3

public class Main {


    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

        String str = in.nextLine();

        in.close();

        str = str.replaceAll("RL+", "RL");

        str = str.replaceAll("R+L", "RL");

        str = str.replaceAll("(RL)+", "R");

        System.out.println(str.length());

        

    }

    

}



2017-09-16 17:07

void Q2(){

string s;

cin >> s;

int L = -1, R = -1;

//从左到右找R

for (int i = 0; i < s.size(); ++i){

if (s[i] == 'R'){

R = i;

break;

}

}

if (R == -1){

cout << s.size() << endl;

return;

}

//从右到左找L

for (int i = s.size() - 1; i >= 0; --i){

if (s[i] == 'L'){

L = i;

break;

}

}

if (L == -1){

cout << s.size() << endl;

return;

}



if (L < R){

cout << s.size() << endl;

return;

}


int sumL = 0;

int sumR = 0;

for (int i = R; i < s.size(); ++i){

if (s[i] == 'L')

sumL++;

}

for (int i = L; i >= 0; --i){

if (s[i] == 'R')

sumR++;

}

//int sum = sumR>sumL ? sumR : sumL;

int sum = sumR + sumL;

cout << s.size() - sum + 1 << endl;

return;

}



2017-09-16 17:07

我的思路:利用编码,如果L右边没有R,那么要把L算进去。如果R后面有L,肯定是保留一个R。

O(n)的复杂度。

AC代码如下:

#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 100008;

char line[maxn];

struct Seq {
    char op;
    int l;
};

struct Seq seq[maxn];
int seq_idx;
int main() {
//    freopen("in.txt", "r", stdin);
    while (scanf("%s", line) != EOF) {
        char pre_op = 'X';
        int length = strlen(line);
        seq_idx = 0;
        for (int i = 0; i < length; i++) {
            if (line[i] != pre_op) {
                seq_idx++;
                seq[seq_idx].l = 1;
                seq[seq_idx].op = line[i];
                pre_op = line[i];
            }
            else {
                seq[seq_idx].l += 1;
            }
        }
        int has_right = 0;
        int ans = 0;
        for (int i = 1; i <= seq_idx; i++) {
            if (seq[i].op == 'L' && has_right == 0) {
                ans += seq[i].l;
            }
            else if (seq[i].op == 'L' && has_right == 1) {
                continue;
            }
            else if (seq[i].op == 'R') {
                if (i < seq_idx) {
                    has_right = 1;
                    continue;
                }
                else {
                    ans += seq[i].l;
                }
            }
        }
        if (has_right) {
            ans += 1;
        }
        cout << ans << endl;
    }
    return 0;
}




2017-09-16 17:09
#include<iostream>
#include<string>
using namespace std;

int main()
{
	string str;
	while (cin >> str)
	{
		while (str.find("RL") != string::npos)
		{
			int index = str.find("RL");
			if (index != 0)
			{
				if (str[index - 1] == 'R')
					str.erase(index, 1);
				else
					str.erase(index + 1, 1);
			}
			else
				str.erase(index + 1, 1);
		}
		cout << str.length()<<endl;
	}
	return 0;
}


2017-09-16 17:12

想着用编程的方法解问题,结果70。。

早知道就直接推规律了。。。

2017-09-16 17:12
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main() {
	string in;
	cin >> in;
	int n = in.size();
	int remain1;
	for (remain1= 0; remain1 < n&&in[remain1] == 'L'; ++remain1) {}
	int remain2;
	for(remain2=0;remain2<n&& in[n-1-remain2] == 'R'; ++remain2){}
	int remain = remain1 + remain2;
	if (remain == n) {
		cout << remain << endl;
		return 0;
	}
	else
		cout << remain + 1 << endl;
	return 0;
		
}


2017-09-16 17:13

第一个R和最后一个L之间的串全部可以“踢出去”,所以只需找到第一个R和最后一个L的下标;

若indexR > index L , 查找失败,输出字符串长度length;

否则输出

length - (lastL - firstR)

代码如下:

import java.util.Scanner;

/**
 * Created by oukohou on 2017/9/16.
 * 
 * If this runs wrong, don't ask me, I don't know why;
 * If this runs right, thank god, and I don't know why.
 * Maybe the answer, my friend, is blowing in the wind.
 */
public class Quarrel {

    public static int getLeftPeople(char[] chars) {
        if (chars.length == 1) {
            return 1;
        }

        int length = chars.length;
        int sum = length;
        int firstR = 0, lastL = length - 1;
        boolean foundR = false, foundL = false;
        
        for (int i = 0; i < length; i++) {
            if (chars[i] == 'R' && !foundR) {  // 查找第一个R 
                foundR = true;
                firstR = i;
            }

            if (chars[length - 1 - i] == 'L' && !foundL) { // 查找第一个L
                foundL = true;
                lastL = length - 1 - i;
            }

            if (foundL && foundR) {
                break;
            }
        }
        
        if (foundL && foundR && firstR < lastL) {  // 找到,并且R在L左边,则更新sum 
            sum = length - (lastL - firstR);
        }
        return sum;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String string = scanner.next();
        char[] chars = string.toCharArray();
        int sum = getLeftPeople(chars);
        System.out.println(sum);
    }
}

代码已同步到oukohou的github,欢迎 star and fork. 


2017-09-16 17:13
1

哪位大神解释下什么意思。。

只要有一个LR 匹配,不就可以一直消下去么。。 

2017-09-16 17:13
public static void sort(StringBuffer s){
		int len = s.length();
		int count =0;
		int left = s.indexOf("L");
		int right = s.indexOf("R");
		if(left==-1||right==-1){
			System.out.println(len);
		}
		if(s.charAt(0)=='R'){
			if(s.charAt(len-1)=='R'){
				left = s.lastIndexOf("L");
				System.out.println(len-left+1);
			}
			if(s.charAt(len-1)=='L'){
				System.out.println(1);
			}
		}
		if(s.charAt(0)=='L'){
			left = s.indexOf("R");
			count = left;
			s.delete(0,left);
			len =s.length();
			
			if(s.charAt(len-1)=='R'){
				left = s.lastIndexOf("L");
				if(left!=-1){
					System.out.println(len-left+1+count);
				}else{
					System.out.println(count+len);
				}
				
			}
			if(s.charAt(len-1)=='L'){
				System.out.println(1+count);
			}
		}


2017-09-16 17:15

想法很简单,从左看,连续的L肯定留下,同理右边也一样。

中间如果还有剩余,最后只会剩一个。

public static int solution(String s){
    int count=0;
    for(int i=0;i<s.length();i++){
        if(s.charAt(i)=='L'){
            count++;
        }else{
            break;
        }
    }
    for(int i=s.length()-1;i>=0;i--){
        if(s.charAt(i)=='R'){
            count++;
        }else{
            break;
        }
    }
    if(count==s.length()){
        return count;
    }else
        return count+1;
}


2017-09-16 17:30
coder_MkDotqWy 回复 coder_M8PC47E5

是要R在左,L在右才能面对面吧~

2017-09-16 17:59
#include <stdio.h>
#include <string.h>

int main()
{
	char str[10];
	int i = 1;
	int n,j,Num_Remain;
	
	printf("Please Enter: \n");
	gets(str);
	//printf("%s\n",str);
	Num_Remain = strlen(str);
	
	for(n = 0;str[n] != '\0';n++)  
	{
		if((str[n] == 'R') && (str[n++] == 'L'))
		{
			
			if( i%2 )
			{
				i++;
				for(j = n;str[j] != '\0';j++)
					str[j] = str[j++];
				Num_Remain--;
				printf("%d",Num_Remain);
				n--;
			}
			
			else
			{
				i++;
				for(j = n + 1;str[j] != '\0';j++)
					str[j] = str[j++];
				Num_Remain--;
				n--;
			}
		}
	}
	
	printf("%d",Num_Remain);
	return 0; 
}

求问大神,为什么这个运行结果不对,正确率为10%是个什么鬼。。。

2017-09-16 18:00

由于只要是(*)这种形式的字符串(*代表任意),就能减为一个字符,所以只要找两端的L和R有几个就可以

2017-09-16 18:45

#include <iostream>

#include <stdio.h>


using namespace std;


int main()

{

char arr[] = "LRRLRLL";

int arrLen = strlen(arr);


if (arrLen<1 || arrLen>100000)

{

return -1;

}


for (int i=0;i<arrLen-1;i++)

{

if(arr[i] != arr[i+1])

arr[i]= NULL;

else

continue;

}


int num=0;

for (int i=0;i<arrLen;i++)

{

if(arr[i] != NULL)

num++;

}

cout<<num<<endl;


return 0;

}


2017-09-17 00:26
#include <iostream>
#include <string>

using namespace std;

int maxDelet(string str) {
    int max = 0;
    if(str.empty() || str.length() == 1)
        return max;
    for(int i = 0; i < str.length() - 1; i++) {
        if(str[i] == str[i+1] ||(str[i] == 'L' && str[i+1] == 'R'))
            continue;
        else {
            string stmp1 = str;
            string stmp2 = str;
            int max1 = maxDelet(stmp1.erase(i,1));
            int max2 = maxDelet(stmp2.erase(i+1,1));
            if(max1 >= max2) {
                str.erase(i,1);
                max = max1+1;
            }
            else {
                str.erase(i+1,1);
                max = max2+1;
            }
            break;
        }
    }
    return max;
}

int main(int argc, const char * argv[]) {
    string str;
    while (cin >> str) {
        size_t len = str.length();
        int maxd = maxDelet(str);
        cout << len - maxd << endl;
    }
    return 0;
}


2017-09-17 15:44
添加回复
回到顶部