2023/04/24 ~ 25 刷题记录

 A - Sort the Subarray

大致题义:Monocarp有一个包含n个整数的数组a。他决定选择两个整数l和r,使1< 2rn,然后对子数组进行排序。子数组a[1 ..]R]是数组a中包含元素a1, al+1, al+2,…的部分。, ar-1, ar)按非降序排列。在对子数组进行排序之后,Monocarp获得了一个新的数组,我们用'表示。例如,如果a =[6,7,3,4,4,4,6,5],并且Monocarp选择了l = 2,r = 5,那么a' =[6,3,4,4,7,6,5]。已知数组a和a'找出Monocarp可能选择的整数l和r。如果有多对值(l,r),找到与最长子数组对应的值。

题解:找到不同的元素的位置并向左右两边寻找边界。输出边界。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int t = sc.nextInt();
        while (t-- != 0) {
            int tempL = -1, l = -1, tempR = -1, r = -1;

            int len = sc.nextInt();
            int[] a = new int[len];
            int[] b = new int[len];
            // 输入A数组
            for (int i = 0; i < len; i++) {
                a[i] = sc.nextInt();
            }
            for (int i = 0; i < len; i++) {
                b[i] = sc.nextInt();
                // 获取范围最小的边界
                if (a[i] != b[i])
                    if (l == -1)
                        l = i;
                    else
                        r = i;
            }

            // 从边界出发,寻找真正边界
            while (l > 0) {
                if (b[l-1] <= b[l])
                    l --;
                else
                    break;
            }
            while (r + 1 < len) {
                if (b[r] <= b[r+1])
                    r ++;
                else
                    break;
            }
            
            // 打印序号,下标要加一
            System.out.println(++l + " " + ++r);
        }
    }
}

B - Tear It Apart

 大致题义:

给你一个字符串 s,由小写拉丁字母组成。

在一个操作中,可以选择其中的多个(一个或多个)位置,以便没有两个选定的位置彼此相邻。然后,从字符串中删除所选位置上的字母。生成的零件在不更改其顺序的情况下连接。

制作所有字母所需的最小操作数是多少 一样?

题解:

        贪心思想。将 26 个字母都算一遍,求最小值。因为消除的字符不能连续,也就是天然的将每种字符分隔。然后目标就是消除分隔内的字符串,求得最小的消除次数。每次操作只需要算出每段区间中最长的区间,设区间长度为len,最少需要的操作次数为1 + log2^len。Java中没有以2为底的log,所以需要用到换底公式。

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int t = sc.nextInt();
        sc.nextLine();
        while (t-- != 0) {
            ArrayList<ArrayList<Integer>> arrayLists = new ArrayList<>();
            for (int i = 0; i < 26; i++) {
                arrayLists.add(new ArrayList<>());
            }

            String s = sc.nextLine();
            StringBuilder stringBuilder = new StringBuilder(s);
            for (int i = 0; i < stringBuilder.length(); i++) {
                char c = stringBuilder.charAt(i);

                arrayLists.get(c - 'a').add(i);
            }

            int ans = 1 << 30;
            for (int i = 0; i < 26; i++) {
                ArrayList<Integer> integers = arrayLists.get(i);
                // 边界 用于判断最后一个对呀的字母到边界有多少字母
                integers.add(stringBuilder.length());

                int temp = -1, m = 0;

                for (Integer integer : integers) {
                    m = (int) Math.max(m, Math.log(integer - temp - 1) / Math.log(2) + 1);

                    temp = integer;
                }

                ans = Math.min(ans, m);
            }

            System.out.println(ans);
        }
    }
}

C - Yura's New Name

大致题义:

在举办了一次团体比赛后,男孩Yura非常疲惫,想改变自己的生活,搬到日本。为了纪念这样的变化,尤拉将他的名字改成了好听的名字。
被这个想法迷住了,他已经想出了一个名字。s仅由字符“”和(“^”组成。但有一个问题――尤拉喜欢笑脸“A八)1和“^^”。因此,该名称的任何字符都必须是至少一个此类笑脸的一部分。请注意,只有名称的连续字符才能是笑脸。
更正式地说,考虑字符串中字符串“^_^"和“^^”的所有匹配项s.那么所有这些事件都必须覆盖整个字符串s,可能与交叉点。例如,在字符串fA_1M_A_^”中,位置的字符3,4,9,10和11不包含在任何笑脸中,其他角色在位置1,2,5,6,7和8包含在笑脸内。
在一个操作中,Jura可以在他的名字中插入一个字符“_”和"”s(您可以将其插入字符串中的任何位置)。他要求你告诉他你需要做的最少操作次数,以使这个名字符合尤拉的标准。

题解:

        如注释


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int t = sc.nextInt();
        sc.nextLine();
        while (t-- != 0) {
            String s = sc.nextLine();

            char[] chars = s.toCharArray();

            int ans = 0;

            // 必须以 '^' 开头
            if (chars[0] != '^')
                ans ++;

            // 碰到了连续两个 '_' 则插入一个 '^'
            for (int i = 0; i < chars.length - 1; i++) {
                if (chars[i] == '_' && chars[i+1] != '^')
                    ans ++;
            }

            // 如果最后一个字符为'_',则需要在最后插入 '^'
            // 最后一个字符为 '^',则只要前面有字符就可以组成“笑脸”
            if (chars[chars.length-1] == '_')
                ans ++;
            // 考虑特殊情况,长度为 1,且为'^'
            else if (chars.length == 1)
                ans ++;

            System.out.println(ans);
        }
    }
}

F - Li Hua and Maze

 水题一道~

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int t = sc.nextInt();
        sc.nextLine();
        while (t-- != 0) {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();

            System.out.println(Math.min(fun(n, m, x1, y1), fun(n, m, x2, y2)));
        }
    }

    static int fun(int n, int m, int x, int y) {
        if (x == 1 || x == n) {
            if (y == 1 || y == m)
                return 2;
            return 3;
        }

        if (y == 1 || y == m) {
            return 3;
        }

        return 4;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值