题解 | I. 走地鸡地走

走地鸡地走

https://ac.nowcoder.com/acm/contest/121614/I

I. 走地鸡地走

模拟题,注意到 ,并且几个条件都只需要判断前几步

坑点在于,转向 的定义是不同时才视为转向,所以 UURRDDLLUU 其实也发生了连续四次转向都为顺时针的情况

可以在 的时间复杂度内完成,其中 是一个小常数

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

#define fType int
#define foreach(x, a, b) for (fType x = a, _end_ = b; x <= _end_; x++)
#define foreach_sub(x, a, b) for (fType x = a, _end_ = b; x >= _end_; x--)
#define tpl make_tuple

const string sw = "URDL";

int main()
{
    ios::sync_with_stdio(0), cin.tie(0);

    int _;
    cin >> _;

    while (_--)
    {
        int n;
        string s;
        cin >> n >> s;

        auto get = [&](char x) -> int
        {
            foreach (w, 0, 3)
                if (sw[w] == x) return w;
            return -1;
        };

        // a -> b
        auto dif = [&](int a, int b) -> int { return (b - a) - (((b - a) >> 31) << 2); };

        bool valid = 1;
        foreach (i, 1, n - 1)
        {
            if (dif(get(s[i]), get(s[i - 1])) == 2)
            {
                valid = 0;
                break;
            }
        }

        if (!valid)
        {
            cout << "NO\n";
            continue;
        }

        foreach (i, 3, n - 1)
        {
            if (s[i] == s[i - 1] && s[i] == s[i - 2] && s[i] == s[i - 3])
            {
                valid = 0;
                break;
            }
        }

        if (!valid)
        {
            cout << "NO\n";
            continue;
        }

        string t;
        t.reserve(n);
        for (auto ch : s)
            if (t.empty() || t.back() != ch) t.push_back(ch);
        n = t.size();
        s = t;

        foreach (i, 4, n - 1)
        {
            auto [d1, d2, d3, d4] = tpl(dif(get(s[i - 4]), get(s[i - 3])), dif(get(s[i - 3]), get(s[i - 2])),
                                        dif(get(s[i - 2]), get(s[i - 1])), dif(get(s[i - 1]), get(s[i])));

            if (d1 == d2 && d1 == d3 && d1 == d4)
            {
                valid = 0;
                break;
            }
        }

        if (!valid)
        {
            cout << "NO\n";
            continue;
        }

        cout << "YES\n";
    }

    return 0;
}

扩展思考:如果将规定 改成 "不允许出现连续 次转向都是顺时针或逆时针","不允许出现连续 次行走都向同一个方向",且 ,怎么做呢?

全部评论

相关推荐

影04714:把图书管理系统那个项目经验内容适当的减少掉,然后改成据为己有不要说团队项目,因为图书管理系统这类常见的谁来了都能独立写出来,提问能圆过来即可
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务