L1-110 这不是字符串题 - java

题目解析

按照要求执行指定操作

  • 操作为1
    • 将序列a替换为序列b
  • 操作为2
    • 在相邻两个数字之和为偶数的中间插入这两个数的平均值
  • 操作为3
    • 将L到R之间的所有数翻转

解题思路

这道题目有两种方法实现

  • 第一种: 暴力模拟

    • 操作为1时

      • 先将两个序列先进行输入

      • 再判断原序列当中是否存在指定序列a

        • 可以暴力判断

          // 存在连续的整数序列下的起始位置
          int start = -1;
          for (int i = 1; i <= n; i++)
          {
              // 判断是否存在连续的整数序列
              for (int j = 1; j <= l1; j++)
              {
                  // 从当前位置开始到达的第j个位置与指定的连续序列不同,则表示当前从第i个位置开始的整数序列不存在
                  if (shu[i + j - 1] != a[j]) break;
                  // 如果能完全找到连续的整数序列,则替换起始位置
                  if (j == l1) start = i;
              }
          
              // 存在连续的整数序列
              if (start != -1) break;
          }
          
        • 也可以利用小技巧

          // 存在连续的整数序列下的结束位置
          int end = -1;
          // 记录序列a在原序列中连续出现的次数
          int j = 1;
          for (int i = 1; i <= n; i++) 
          {
              // 如果当前的数与第j个数相同
              if (shu[i] == a[j]) j++;
                  // 如果当前的数与第j个数不相同,则将其与序列a中的第1个数进行判断
              else if (shu[i] == a[1]) j = 2;
                  // 如果都不相同,则重置
              else j = 1;
              // 如果连续出现的次数超过l1个,则表示序列a在原序列中存在
              if (j > l1) 
              {
                  end = i;
                  break;
              }
          }
          
      • 如果存在

        • 将数组中的序列a替换为序列b
    • 操作为2时

      • 依次枚举相邻两个元素
      • 判断这两个元素之和是否为偶数
        • 如果两个元素之和是偶数,则将这两个元素的平均值插入其中
    • 操作为3时

      • 翻转l到r之间的所有数

  • 第二种: 利用类库“SB”实现
  • 可以发现给定的正整数的范围都是1261 \sim 26, 可以发现其满足字母aza \sim z的范围。由于给定的操作有替换、翻转的功能,正好可以利用字符串快速实现。
    • 操作为1时
      • 利用indexOf判断序列a原序列中存在的位置
      • 如果存在, 则利用拼接的方法将序列b替换原序列中的序列a
    • 操作为2时
      • 依次枚举相邻两个元素
      • 判断这两个元素之和是否为偶数
        • 如果两个元素之和是偶数,则将这两个元素的平均值插入其中
    • 操作为3时
      • 利用reverse()函数将StringBuilder的字符串进行翻转
      • 在利用拼接的方法翻转指定lrl \sim r区间即可

代码

暴力模拟

import java.io.*;

public class Main
{
    static int N = (int) 2e5;
    static int shu[] = new int[N + 10];
    static int res[] = new int[N + 10];
    static int a[] = new int[N + 10];
    static int b[] = new int[N + 10];

    static int n;

    static void op1() throws IOException
    {
        int l1 = ini();
        for (int i = 1; i <= l1; i++) a[i] = ini();

        int l2 = ini();
        for (int i = 1; i <= l2; i++) b[i] = ini();

        // 存在连续的整数序列下的起始位置
        int start = -1;
        for (int i = 1; i <= n; i++)
        {
            // 判断是否存在连续的整数序列
            for (int j = 1; j <= l1; j++)
            {
                // 从当前位置开始到达的第j个位置与指定的连续序列不同,则表示当前从第i个位置开始的整数序列不存在
                if (shu[i + j - 1] != a[j]) break;
                // 如果能完全找到连续的整数序列,则替换起始位置
                if (j == l1) start = i;
            }

            // 存在连续的整数序列
            if (start != -1) break;
        }
        // 如果不存在连续的整数序列
        if (start == -1) return;

        // 执行插入操作(依次存入 1~start, 替换后的内容, start+l1~n)
        int pos = 0;
        for (int i = 1; i < start; i++) res[++pos] = shu[i];
        for (int i = 1; i <= l2; i++) res[++pos] = b[i];
        for (int i = start + l1; i <= n; i++) res[++pos] = shu[i];

        // 更换数组
        n = pos;
        for (int i = 1; i <= n; i++) shu[i] = res[i];
    }

    static void op2() throws IOException
    {
        int pos = 1;
        for (int i = 1; i < n; i++)
        {
            // 将当前位置的数填入res中
            res[pos++] = shu[i];
            // 如果满足条件,则在中间位置插入平均值
            if ((shu[i] + shu[i + 1]) % 2 == 0) res[pos++] = (shu[i] + shu[i + 1]) / 2;
        }
        // 填入最后的一个值
        res[pos] = shu[n];

        // 更换数组
        n = pos;
        for (int i = 1; i <= n; i++) shu[i] = res[i];
    }

    static void op3() throws IOException
    {
        int l = ini();
        int r = ini();

        // 翻转区间内的数组
        for (int i = 1; i < l; i++) res[i] = shu[i];
        for (int i = r, j = l; i >= l; i--, j++) res[j] = shu[i];
        for (int i = r + 1; i <= n; i++) res[i] = shu[i];

        // 更换数组
        for (int i = 1; i <= n; i++) shu[i] = res[i];
    }

    static void print()
    {
        for (int i = 1; i <= n; i++)
        {
            if (i != 1) out.print(" ");
            out.print(shu[i]);
        }
        out.println();
    }

    public static void main(String[] args) throws IOException
    {
        n = ini();
        int m = ini();
        for (int i = 1; i <= n; i++) shu[i] = ini();

        while (m-- > 0)
        {
            int op = ini();
            if (op == 1) op1();
            else if (op == 2) op2();
            else if (op == 3) op3();
        }
        print();

        out.flush();
        out.close();
    }

    static StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(System.out);

    static int ini() throws IOException
    {
        sc.nextToken();
        return (int) sc.nval;
    }

}

类库“SB”

import java.io.*;

public class Main
{
    static StringBuilder s;

    // 将输入的数字序列转换为字符串
    static StringBuilder getString(int n) throws IOException
    {
        StringBuilder ans = new StringBuilder();
        for (int i = 1; i <= n; i++)
        {
            int x = ini();
            ans.append((char) ('a' + x - 1));
        }
        return ans;
    }

    static void op1() throws IOException
    {
        int l1 = ini();
        StringBuilder a = getString(l1);

        int l2 = ini();
        StringBuilder b = getString(l2);

        // 获取序列a在序列s中的位置
        int start = s.indexOf(a.toString());

        // 如果存在,则将序列a替换序列b
        if (start != -1) s = new StringBuilder(s.substring(0, start) + b + s.substring(start + l1));
    }

    static void op2() throws IOException
    {
        // 将s转换为char数组
        char res[] = s.toString().toCharArray();
        // 清空s
        s = new StringBuilder();
        for (int i = 0; i < res.length - 1; i++)
        {
            // 将当前位置的字符填入s中
            s.append(res[i]);

            int ans = (res[i] - 'a' + 1) + (res[i + 1] - 'a' + 1);
            // 如果满足条件,则在中间位置插入平均值
            if (ans % 2 == 0) s.append((char) (ans / 2 + 'a' - 1));
        }
        // 填入最后的一个值
        s.append(res[res.length - 1]);
    }
 
    static void op3() throws IOException
    {
        int l = ini() - 1;
        int r = ini() - 1;

        // // 翻转区间内的数组
        s = new StringBuilder( s.substring(0, l) + new StringBuilder(s.substring(l, r + 1)).reverse() + s.substring(r + 1) );
    }

    static void print()
    {
        char res[] = s.toString().toCharArray();
        for (int i = 0; i < res.length; i++)
        {
            if (i != 0) out.print(" ");
            out.print(res[i] - 'a' + 1);
        }
        out.println();
    }

    public static void main(String[] args) throws IOException
    {
        int n = ini();
        int m = ini();
        s = getString(n);

        while (m-- > 0)
        {
            int op = ini();
            if (op == 1) op1();
            else if (op == 2) op2();
            else if (op == 3) op3();
        }
        print();

        out.flush();
        out.close();
    }

    static StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(System.out);

    static int ini() throws IOException
    {
        sc.nextToken();
        return (int) sc.nval;
    }

}

indexOf

StringBuilder


团体程序设计天梯赛-练习集-java

赞赏