首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >完美走位

完美走位

原创
作者头像
代码小李
发布2025-01-27 19:51:29
发布2025-01-27 19:51:29
1230
举报

题目

在第一人称射击游戏中,玩家通过键盘的 ASDW 四个按键控制游戏人物分别向左、向后、向右、向前进行移动,从而完成走位。

假设玩家每按动一次键盘,游戏人物会向某个方向移动一步,如果玩家在操作一定次数的键盘并且各个方向的步数相同时,此时游戏人物必定会回到原点,则称此次走位为完美走位

现给定玩家的走位(例如:ASDA),请通过更换其中一段连续走位的方式使得原走位能够变成一个完美走位。其中待更换的连续走位可以是相同长度的任何走位。

请返回待更换的连续走位的最小可能长度。若果原走位本身是一个完美走位,则返回 0

输入

输入为由键盘字母表示的走位s,例如:ASDA

输出

输出为待更换的连续走位的最小可能长度

备注

  1. 走位长度 1 ≤ s.length ≤ 10^5
  2. s.length4 的倍数
  3. s 中只含有 A, S, D, W 四种字符

要解决这个问题,我们需要找到一个最小的连续子串,通过更换这个子串使得整个走位变成一个完美走位。完美走位的定义是每个方向(A, S, D, W)的步数相同。

解题思路

  1. 统计步数:首先统计每个方向的步数。
  2. 寻找最小替换长度:通过滑动窗口的方法,找到一个最小的连续子串,使得替换后每个方向的步数相同。

代码实现(C#)

代码语言:csharp
复制
using System;
using System.Collections.Generic;

class PerfectWalk
{
    public static int MinReplaceLength(string s)
    {
        int n = s.Length;
        int[] count = new int[4]; // 分别记录 A, S, D, W 的步数

        // 统计每个方向的步数
        foreach (char c in s)
        {
            switch (c)
            {
                case 'A': count[0]++; break;
                case 'S': count[1]++; break;
                case 'D': count[2]++; break;
                case 'W': count[3]++; break;
            }
        }

        // 如果已经是完美走位,返回 0
        if (count[0] == count[1] && count[1] == count[2] && count[2] == count[3])
        {
            return 0;
        }

        // 滑动窗口
        int left = 0;
        int minLen = n;
        for (int right = 0; right < n; right++)
        {
            // 更新当前窗口内的步数
            switch (s[right])
            {
                case 'A': count[0]--; break;
                case 'S': count[1]--; break;
                case 'D': count[2]--; break;
                case 'W': count[3]--; break;
            }

            // 检查当前窗口是否满足条件
            while (IsPerfect(count))
            {
                minLen = Math.Min(minLen, right - left + 1);
                // 移动左指针
                switch (s[left])
                {
                    case 'A': count[0]++; break;
                    case 'S': count[1]++; break;
                    case 'D': count[2]++; break;
                    case 'W': count[3]++; break;
                }
                left++;
            }
        }

        return minLen;
    }

    private static bool IsPerfect(int[] count)
    {
        return count[0] == count[1] && count[1] == count[2] && count[2] == count[3];
    }

    public static void Main(string[] args)
    {
        string s = Console.ReadLine();
        int result = MinReplaceLength(s);
        Console.WriteLine(result);
    }
}

解释

  1. 统计步数
    • 使用一个数组 count 来记录每个方向的步数。
    • 遍历输入字符串 s,更新 count 数组。
  2. 检查是否已经是完美走位
    • 如果 count 数组中的所有值都相等,说明已经是完美走位,直接返回 0。
  3. 滑动窗口
    • 使用两个指针 leftright 来表示当前窗口的左右边界。
    • 每次移动右指针时,更新 count 数组。
    • 检查当前窗口是否满足完美走位的条件,如果满足,更新最小长度 minLen
    • 移动左指针以保持窗口大小,并更新 count 数组。
  4. 返回结果
    • 最终返回 minLen,即待更换的连续走位的最小可能长度。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目
  • 输入
  • 输出
  • 备注
    • 解题思路
    • 代码实现(C#)
    • 解释
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档