算法练习 第三周

算法练习第三周

其实应该从第一周就开始写一下的, 记录下自己的题解.

本周题目列表:

https://www.luogu.com.cn/contest/40663#problems

A: 【深基2.例8】再分肥宅水

https://www.luogu.com.cn/problem/P5706

太过基础了, 不知道为什么选择了这个题在题单里

可能唯一麻烦的地方是输出要精确到小数点后3位

直接输出double类型的话 默认会变得好长好长

所以我选择了使用System.out.printf("%.3f",变量);方法格式化输出, 以此保留3位小数

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        // 输入处理
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] inArr = br.readLine().split(" ");
        // 总共多少毫升的水
        double all = Double.parseDouble(inArr[0]);
        // 多少人分
        int n = Integer.parseInt(inArr[1]);
        // 每人分多少
        double avg = all / n;
        System.out.printf("%.3f", avg);
        // 杯子数
        int numberOfCups = n * 2;
        System.out.println("
" + numberOfCups);
    }
}

B: Pangram

https://www.luogu.com.cn/problem/CF520A

这个题要求判断输入的字符串是否包含所有a-z的字符,不区分大小写

这个题令我想到了一句话The Quick Brown Fox Jumps Over The Lazy Dog

这个题我想到的思路是利用Set集合的特点: Set集合存储的元素不重复

这样的话, 就可以直接把每个字符add到Set集合中去, Set集合中遇到重复元素会自动覆盖掉已存在集合中的元素.

最后只需要判断Set集合的长度是否为26就可以知道句子是否包含所有的a-z的字符.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) throws IOException {     
        // 输入处理
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 字符串的长度
        br.readLine();
        // 输入字符串
        String s = br.readLine();
        
        // 转全大写
        char[] chars = s.toUpperCase().toCharArray();
        
        // 遍历添加到set集合中
        Set<Character> set = new HashSet<>();
        for (char c : chars) {
            set.add(c);
        }
        if (set.size() == 26) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}

C: 表达式括号匹配

https://www.luogu.com.cn/problem/P1739

这个题首先就想到了可以利用栈结构处理. 我的代码写的有点繁琐了, 有优化的空间 (但我现在不想优化 ~ )

可以根据栈的后进先出的特点, 每次遇到一个左括号就进栈, 每次遇到一个右括号就出栈, 最后判断栈是否为空, 为空则说明括号两两匹配

这里我想到了栈, 所以直接就使用了Stack, 其实仅仅是要计算栈的长度, 可以不用Stack实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException {
        // 输入处理
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String expression = br.readLine();
        
        String result = checkBracketMatching(expression);
        System.out.println(result);
    }
    
    private static String checkBracketMatching(String expression) {
        // 用栈检查是否匹配括号
        Stack<Character> stack = new Stack<Character>();
        // 遍历字符串
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(') {
                stack.push(c);
            }
            if (c == ')') {
                if (stack.size() > 0 && stack.peek() == '(') {
                    stack.pop();
                } else {
                    return "NO";
                }
            }
        }
        if (stack.size() > 0) {
            return "NO";
        }
        return "YES";
    }
}

D: 进制转换

https://www.luogu.com.cn/problem/P2084

没想到什么好方案, 就遍历输入的字符串, 然后根据规律硬拼

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        // 输入处理
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] inArr = br.readLine().split(" ");
        int m = Integer.parseInt(inArr[0]);
        String number = inArr[1];
        // 使用StringBuilder拼接字符串
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < number.length(); i++) {
            char c = number.charAt(i);
            if (c != '0') {
                s.append(c).append("*").append(m).append("^").append(number.length() - i - 1).append("+");
            }
        }
        if (s.length() > 1) {
            s.deleteCharAt(s.length() - 1);
        }
        System.out.println(s);
    }
}

E: 眼红的Medusa

https://www.luogu.com.cn/problem/P1571

这个题, 读完题简单的想了下, 我觉得题目是在求两个容器的交集

但是题目要求按顺序输出结果, 于是我直接选择造了两个List集合

然后使用集合的retainAll方法对两个集合的元素求交集

第一次提交妥妥的超时......

初步怀疑是数据量大, 导致List集合求交集速度会变慢, 求交集的算法之前没有研究过, 于是这次简单的翻阅了下源码.

突然想起来Set集合的存在, 索性就试试Set集合和List集合求交集, 因为要求按顺序输出, 所以没法用两个Set集合...我倒是想用两个Set集合, 我觉得Set应该会比List快一些.

果然这次提交就没有超时, 看来Set集合快了不止一点.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        // 输入处理
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] line1 = br.readLine().split(" ");
        if ("0".equals(line1[0]) || "0".equals(line1[1])) {
            return;
        }
        String[] line2 = br.readLine().split(" ");
        String[] line3 = br.readLine().split(" ");
        
        List<String> stiAwardList = new ArrayList<>(Arrays.asList(line2));
        Set<String> scAwardList = new HashSet<>(Arrays.asList(line3));
        // 求交集
        stiAwardList.retainAll(scAwardList);

        // 打印输出
        stiAwardList.forEach(o -> System.out.print(o + " "));
    }
}
原文地址:https://www.cnblogs.com/yao-xi/p/14374651.html