洛谷 P9503『MGOI』Simple Round I | B. 魔法照相馆 の 题解

发布时间 2023-09-13 11:37:23作者: NFGase

这道题是一道模拟题,坑点不多,但是细节特多,所以导致大部分人 $A$ 不了这道题。这道题我也写了注释,如果思路没明白可以看代码和注释的。

先创建一个长度为 $3$ 的字符串 $s1$ ,这个字符串的意思就是模拟现在的这几个幕布的情况,这里分了四个字符代表着四种情况,详细如下

  • 该字符串 $s1$ 下标为 $0$ 时该元素若为 R 则代表最左侧的颜色为红色的幕布被拉下。
  • 该字符串 $s1$ 下标为 $1$ 时该元素若为 B 则代表中间的颜色为蓝色的幕布被拉下。
  • 该字符串 $s1$ 下标为 $2$ 时该元素若为 W 则代表最右侧的颜色为白色的幕布被拉下。
  • 该字符串 $s1$ 任意下标内的元素里面若为 N 则代表幕布被拉上去。

要注意,字符串 $s1$ 的定义必须是 s1 = "RBW"; 这样才能满足题目对于幕布的顺序要求。

之后我们完成基本的输入, $n$ 是指接下来客人们要求的幕布颜色个数, $s$ 则是个字符串,用来存储客户要求的幕布颜色,别忘了定义一个变量 $times$ ,注意别定义成 $time$ ,这样会编译错误,因为会和 $time$ 函数冲突。

正式开始模拟!先创建个循环,遍历一下字符串 $s$ ,如果 $s$ 为 $W$ ,则要判断 s1[2] 是否为 $N$ ,如果是,则代表着幕布已拉上,需要花费 $1$ 个单位时间拉下,之后要更新 s1[2]W ,如果不是 N 则什么也不用做,如果你实在想做点什么,只需要写一个 time += 0; 即可,这样你回顾代码的时候也能看得更明白。

其他情况也比较类似,只不过要判断右边的那个幕布是否拉下,如果拉下则又要花费一个单位时间拉上去,因为会挡住你要用的那个幕布,如果还是不明白,我的代码也有注释,可以搭配代码理解。最后,有问题请私信我,不要在底下评论。

#include <iostream>
#include <string>
using namespace std;
int n, len, times = 0;
string s, s1;
int main(){
    cin >> n >> s;
    len = s.length();
    s1.resize(3);
    s1 = "RBW"; //当前的幕布状态
    for(int i = 0; i < len; i++){
        if(s[i] == 'W'){ //如果客户要求是W
            if(s1[2] == 'W') times += 0; //如果最右边已经拉下了,拍照
            else if(s1[2] == 'N'){ //如果最右边没被拉下
                times++;
                s1[2] = 'W'; //那就拉下去
            }
        }
        else if(s[i] == 'B'){ //如果客户要求是B
            if(s1[2] == 'W'){ //如果最右边被拉下
                times++;
                s1[2] = 'N'; //拉上去
                if(s1[1] == 'B') times += 0; //如果中间被拉下,拍照
                else if(s1[1] == 'N'){ //如果没有
                    times++;
                    s1[1] = 'B'; //那就拉下去
                }
            }
            else if(s1[2] == 'N'){ //如果最右边没被拉下,就不必管了
                if(s1[1] == 'B') times += 0; //如果中间被拉下,拍照
                else if(s1[1] == 'N'){ //如果没有
                    times++;
                    s1[1] = 'B'; //那就拉下去
                }
            }
        }
        else if(s[i] == 'R'){ //如果客户要求是R
            if(s1[2] == 'W'){ //如果最右边被拉下
                times++;
                s1[2] = 'N'; //拉上去
                if(s1[1] == 'B'){ //如果中间被拉下
                    times++;
                    s1[1] = 'N'; //拉上去
                    if(s1[0] == 'R') times += 0; //如果最左边被拉下,拍照
                    else if(s1[0] == 'N'){ //若没有
                        times++;
                        s1[0] = 'R';
                    }
                }
                else if(s1[1] == 'N'){ //如果没被拉下
                    if(s1[0] == 'R') times += 0; //如果最左边被拉下,拍照
                    else if(s1[0] == 'N'){ //若没有
                        times++;
                        s1[0] = 'R';
                    }
                }
            }
            else if(s1[2] == 'N'){ //若没被拉下
                if(s1[1] == 'B'){ //如果中间被拉下
                    times++;
                    s1[1] = 'N'; //拉上去
                    if(s1[0] == 'R') times += 0; //如果最左边被拉下,拍照
                    else if(s1[0] == 'N'){ //若没有
                        times++;
                        s1[0] = 'R';
                    }
                }
                else if(s1[1] == 'N'){ //如果没被拉下
                    if(s1[0] == 'R') times += 0; //如果最左边被拉下,拍照
                    else if(s1[0] == 'N'){ //若没有
                        times++;
                        s1[0] = 'R';
                    }
                }
            }
        }
        // cout << times << "->";
    }
    cout << times;
    return 0;
}