题解 - 取珠子

题目描述

味味妈妈有一串珠子串成的项链,这个项链中的珠子最多有 3 种颜色(红、蓝、白, 分别用 r、b、w 表示)。某天,味味想从妈妈项链中取出一些珠子来玩,妈妈虽然答应了, 但提出了以下条件:
(1)只能在项链中选择一个地方剪断,然后从断开的两端开始依次取出珠子;
(2)每一端取珠子时,如果珠子颜色与该端第一颗珠子颜色相同则可以连续取下去, 直到出现一颗与该端第一颗颜色不同的珠子。如果遇到白色珠子则可根据需要看做蓝色或者 红色。
在这里插入图片描述

味味对于颜色并没有特殊要求,但她想得到尽可能多的珠子。
为方便表示,我们给项链中的珠子按顺时针方向编号,如图-1 和图-2 所示为两种可能的项链情况(珠子都有 11 颗)。
对于图-1 来说,如果在 1 和 2 号珠子之间剪断,则味味可以取到共 2 颗珠子。而如果 在 6 和 7 号珠子之间剪断,则味味可以取到共 5 颗珠子(左边取 3 颗红色 r,右边取 2 颗 蓝色 b),而 5 颗珠子也是味味从这串项链中最多可以取到的珠子数量。
对于图-2 中的项链来说,如果在 1 和 2 号珠子之间剪断,则共可取走 4 颗珠子(将 1 号珠子当做蓝色,这样左边可取 3 颗,右边可取 1 颗蓝色 b)。而如果在 2 和 3 号之间剪断, 则共可取走 6 颗珠子(将 1 号珠子当做蓝色,这样左边可取 4 颗蓝色 b,右边可取 2 颗红 色 r)。
输入
输入共包含二行。第一行一个整数 n,表示项链中珠子的总数。第二行为 一串长度为 n 的字符,由字符 r,b,w 组成。表示项链从某个珠子开始按顺时针方向展开 的珠子排列情况(当然,这个珠子并不一定是味味实际需要剪断的位置)。
输出
输出仅包含一行一个数值,表示按照妈妈的规则,味味最多能得到的珠子数量。
样例输入 Copy
11
wbrrbbwbrbb
样例输出 Copy
6
提示
将 1 号珠子看成蓝色,则在 2 和 3 号珠子之间剪断,味味可得到的 6 颗珠子编号分别为1、2、3、4、10、11;也可在 4 和 5 号珠子间剪断,将 7 号珠子看成蓝色,则味味可得到珠子的编号为 3、4、5、6、7、8。

对于 60%的数据 3≤n≤100
对于 100%的数据 3≤n≤350

题意

给定一个由n个珠子组成的项链(由红、蓝、白组成, 分别用 r、b、w 表示)。

可以任意选择两个珠子中间剪断,从两端开始依次取珠子,每一端取珠子时,如果珠子颜色与该端第一颗珠子颜色相同则可以连续取下去, 直到出现一颗与该端第一颗颜色不同的珠子。如果遇到白色珠子则可根据需要看做蓝色或者红色。

求最大可以取出的珠子数量。

3≤n≤350

分析

看到n的范围,直接暴力模拟,先把字符串扩大一倍(加上它本身),保证每个点都能够取足n个字符。

这个题的坑点比较麻烦。

两端可能会出现白色,这个时候我们就要求两种情况(白为红或者白为蓝)的最大值。

如果两端没有白色,就正常取就行

如果直接模拟从两端取珠子不打标记的话,可能会取重复的珠子,当然能够取到重复的珠子直接输出n就行

代码

#include <cstring>
#include <iostream>
using namespace std;
string s;
int main()
{
    int n;
    cin >> n;
    cin >> s;
    s = s + s;//扩大一倍
    int maxx = 0;
    for (int i = 0; i < n; i++)
    {
        string p = s.substr(i, n);//从i点取n个出来
        char l, r;
        l = p[0], r = p[n - 1];//左端点和右端点
        int count = 2;
        if (l == 'w' || r == 'w')//如果有端点是白色
        {
            if (l == 'w')
            {
                int count1 = 0;
                l = 'r';
                for (int i = 1; i < n; i++)
                {
                    if (p[i] == l || p[i] == 'w')
                    {
                        count1++;
                    }
                    else
                    {
                        break;
                    }
                }
                int count2 = 0;
                l = 'b';
                for (int i = 1; i < n; i++)
                {
                    if (p[i] == l || p[i] == 'w')
                    {
                        count2++;
                    }
                    else
                    {
                        break;
                    }
                }
                count += max(count1, count2);
            }
            else
            {
                for (int i = 1; i < n; i++)
                {
                    if (p[i] == l || p[i] == 'w')
                    {
                        count++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            if (r == 'w')
            {
                int count1 = 0;
                r = 'r';
                for (int i = n - 2; i > 0; i--)
                {
                    if (p[i] == r || p[i] == 'w')
                    {
                        count1++;
                    }
                    else
                    {
                        break;
                    }
                }
                int count2 = 0;
                r = 'b';
                for (int i = n - 2; i > 0; i--)
                {
                    if (p[i] == r || p[i] == 'w')
                    {
                        count2++;
                    }
                    else
                    {
                        break;
                    }
                }
                count += max(count1, count2);
            }
            maxx = max(maxx, count);
        }
        else
        {
            for (int i = 1; i < n; i++)
            {
                if (p[i] == l || p[i] == 'w')
                {
                    count++;
                }
                else
                {
                    break;
                }
            }
            for (int i = n - 2; i > 0; i--)
            {
                if (p[i] == r || p[i] == 'w')
                {
                    count++;
                }
                else
                {
                    break;
                }
            }
            maxx = max(maxx, count);
        }
    }
    cout << min(maxx, n) << endl;//如果有重复的直接输出n即可
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值