Od练习的第三天

奋斗吧
奋斗吧
擅长邻域:未填写

标签: Od练习的第三天 Java博客 51CTO博客

2023-05-10 18:24:05 45浏览

Od练习的第三天,

进军OD的第三天

对称字符串(字符串、递归)

题目描述

Od练习的第三天_字符串

输入示例

Od练习的第三天_算法_02

题目解答
package com.od202305;

import java.util.Scanner;

/**
 * 对称字符串
 */
public class Od007 {

    public static void main(String[] args) {
        //解法1
        getStr();
        //解法二
        getStr2();

    }

    /**
     * 解法一:常规解法,递归拼接后取值,注意:容易出现越界,使用charAt()中int类型的范围有限
     * @return
     */
    public static void getStr(){
        Scanner scanner = new Scanner(System.in);
        int i = scanner.nextInt();
        for (int j = 0; j < i; j++) {
            int n = scanner.nextInt();
            int k = scanner.nextInt();
            String s = doProcess(n);
            System.out.println(s.charAt(k) == 'R' ? "red" : "blue");
        }
    }

    public static String doProcess(int n) {
        if (n == 1) { //当 n 为 1 时输出 R
            return "R";
        }
        String str = doProcess(n - 1); //当 n 大于等于 2 时需要对字符进行反转处理
        String reverseStr = "";
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == 'R') {
                reverseStr += 'B';
            } else {
                reverseStr += 'R';
            }
        }
        return reverseStr + str;
    }

    /**
     * 解法二
     *
     * @return
     */
    public static void getStr2() {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        for (int i = 0; i < T; i++) {
            int n = sc.nextInt();
            long k = sc.nextLong();
            long charNum = (long) Math.pow(2, n - 1); //第 n 行的总字符个数
            int re = doProcess(charNum, k, 0);
            if (re % 2 == 0) {
                System.out.println("red"); //翻转次数为 2 的倍数
            } else {
                System.out.println("blue");
            }
        }
    }

    /**
     * 思路:字符索引如果在翻转的右侧则翻转次数不加一为单,除以一半层层递归判断
     *
     * @param count   字符数量
     * @param cur     字符的索引
     * @param reverse 翻转的次数
     * @return
     */
    public static int doProcess(long count, long cur, int reverse) {
        if (count == 1) {
            return reverse;
        }
        long half = count / 2;
        if (cur < half) { //小于半数说明是经过翻转的部分
            reverse++;
            return doProcess(half, cur, reverse);
        } else {
            return doProcess(half, cur - half, reverse);//2 0 0
        }
    }
}

分界线(字符串、排序)

题目描述

Od练习的第三天_算法_03

输入示例

Od练习的第三天_字符串_04

题目解答
package com.od202305;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * 分界线
 */
public class Od008 {
    public static void main(String[] args) {
        System.out.println(getResult1("ab cd", "ab"));
    }

    /**
     * 解法一
     *
     * @param s1 相当于报纸(newspaper)
     * @param s2 匿名信代表 (anonymousLetter)
     * @return
     */
    public static boolean getResult1(String s1, String s2) {
        String[] s3 = s1.split(" ");
        String[] s4 = s2.split(" ");
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        Arrays.stream(s3).forEach(e1 -> {
            char[] chars = e1.toCharArray();
            Arrays.sort(chars);
            String sortStr = new String(chars);
            list1.add(sortStr);
        });
        Arrays.stream(s4).forEach(e1 -> {
            char[] chars = e1.toCharArray();
            Arrays.sort(chars);
            String sortStr = new String(chars);
            list2.add(sortStr);
        });

        return list1.containsAll(list2);
    }

    public void getResult2() {
        Scanner sc = new Scanner(System.in);
        String[] newspaper = sc.nextLine().split(" ");
        String[] anonymousLetter = sc.nextLine().split(" ");
        boolean res = true;
        for (String anony : anonymousLetter) {
            for (int i = 0; i < newspaper.length; i++) {
                String news = newspaper[i];
                if (anony.length() == news.length() && handle(news, anony)) { //长度相等才有资格匹配
                    newspaper[i] = " "; //使用过的字符串之后就不能使用了
                    break;
                }
                if (i == newspaper.length - 1) { //遍历到最后都没有匹配的,直接 false
                    res = false;
                }
            }
            if (!res) { //已经失败了,跳出循环
                break;
            }
        }
        System.out.println(res);
    }

    /**
     * 通过 char 字符的排序,然后判断是否一一匹配,只要一个不匹配,直接 false * @param news 报纸上的字符串
     *
     * @param anony 匿名信上的字符串
     * @return
     */
    public static boolean handle(String news, String anony) {
        char[] newsChar = news.toCharArray();
        char[] anonyChar = anony.toCharArray();
        Arrays.sort(newsChar);
        Arrays.sort(anonyChar);
        boolean isTrue = true;
        for (int i = 0; i < newsChar.length; i++) {
            if (newsChar[i] != anonyChar[i]) {
                isTrue = false;
            }
        }
        return isTrue;
    }

}

关联端口组合并(set、数组、递归)

题目描述

Od练习的第三天_递归_05

输入示例

Od练习的第三天_递归_06

题目解答
package com.od202305;

import java.util.*;

public class Od009 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int M = sc.nextInt();
        if (M > 10) {
            System.out.println("[[]]");
        } else {
            List<Set<String>> list = new ArrayList<>();
            sc.nextLine();
            for (int i = 0; i < M; i++) {
                String[] strings = sc.nextLine().split(",");
                Set<String> set = new HashSet<>();
                if (strings.length == 1) { //只有一个元素直接添加
                    set.add(strings[0]);
                    list.add(set);
                } else {
                    for (String str : strings) {
                        set.add(str); //数组转化为 set 集合
                    }
                    list.add(set);
                    merge(set, list, list.size() - 1);
                }
            }
            System.out.println(list);
        }

    }

    public static void merge(Set<String> set, List<Set<String>> list, int index) {
        for (int i = 0; i < list.size(); i++) {
            //保证不和自己进行对比
            if (i == index) {
                continue;
            }
            Set<String> setIndex = list.get(i); //当前索引的 set 集合
            Set<String> setTemp = new HashSet<>();
            setTemp.addAll(set);
            setTemp.retainAll(setIndex); //求出 set 和 setIndex 的交集
            if (setTemp.size() >= 2) { //交集大于等于 2 则合并
                set.addAll(setIndex); //set 与 setIndex 合并
//                int beforeIndex = index > i ? i : index; //求出排在前面的 index
//                int afterIndex = beforeIndex == index ? i : index; //靠后的位置
                list.remove(index); //合并的两个 set 进行删除,先删除后面的一个
                list.remove(i);
                list.add(i, set); //将新的 set 放在前面位置
                merge(set, list, i); //将新建的组合再进行判断合并
            }
        }
    }
}
//第二种
/**
     * 合并关联端口组合
     *
     * @param set   进行合并的端口组合
     * @param list  端口组合集合
     * @param index 需要进行合并的组合索引
     */
    public static void merge2(Set<String> set, List<Set<String>> list, int index) {
        for (int i = 0; i < list.size(); i++) {
            if (i == index) {
                continue;
            }
            Set<String> setIndex = list.get(i); //当前索引的 set 集合
            Set<String> setTemp = new HashSet<>();
            setTemp.addAll(set);
            setTemp.retainAll(setIndex); //求出 set 和 setIndex 的交集
            if (setTemp.size() >= 2) { //交集大于等于 2 则合并
                set.addAll(setIndex); //set 与 setIndex 合并
                int beforeIndex = index > i ? i : index; //求出排在前面的 index
                int afterIndex = beforeIndex == index ? i : index; //靠后的位置
                list.remove(afterIndex); //合并的两个 set 进行删除,先删除后面的一
                个
                list.remove(beforeIndex);
                list.add(beforeIndex, set); //将新的 set 放在前面位置
                merge(set, list, beforeIndex); //将新建的组合再进行判断合并
            }
        }
    }

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695