ABC138振り返り
昨日のABC138を振り返る。
A問題
これはif文がわかれば解ける問題なので、詳細は書かない。
if (n < 3200) { System.out.println("red"); } else { System.out.println(s); }
B問題
逆数ってなんだったっけ・・?と一瞬なったものの、問題文にあった式に従ってfor文で回せば通った。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String ns = sc.nextLine(); int n = Integer.parseInt(ns); String inputs = sc.nextLine(); String[] input = inputs.split(" "); double sum = 0; for (int i = 0; i < input.length; i++) { sum += 1 / Double.parseDouble(input[i]); } System.out.println(1 / sum); } }
C問題
問題が少し複雑になってきた。
2個選んで、半分にして、それを順次繰り返していき、最大値を得るってことは、順々に小さいもの2つを選択していくのがいいので、何はともあれまずはソート。
で、どう書こうと思案したところ、「繰り返す」「要素が一つになれば終了」「処理対象はだんだん小さくなっていく(配列の長さが1ずつ減っていく)」という観点から再帰を思いついた。
ただ、PDFの解説を読んだところ、さっぱりわからん状態だった・・。
import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String ns = sc.nextLine(); int n = Integer.parseInt(ns); String inputs = sc.nextLine(); String[] input = inputs.split(" "); double[] nums = new double[input.length]; for (int i = 0; i < input.length; i++) { nums[i] = Integer.parseInt(input[i]); } //まずはソートする Arrays.sort(nums); double result = makeResult(nums); System.out.println(result); } //再帰処理を行う private static double makeResult(double[] nums) { //配列の長さが1になったら終了 if (nums.length == 1) { return nums[0]; } //新しい配列は処理対象の配列より要素数が一つ減る。 double[] newNums = new double[nums.length - 1]; //新しい要素の1番目は処理対象配列の要素の先頭2つを足して割ったものにする。 newNums[0] = (nums[0] + nums[1]) / 2; //あとは配列の要素をコピーすればいいはず for (int i = 1; i < newNums.length; i++) { newNums[i] = nums[i + 1]; } return makeResult(newNums); } }
D問題
アルゴリズム的には正しかったぽいけど、TLEが出てしまったので、計算量的にだめ。
私の考え方としてはとりあえずNodeクラスを作って、各NodeにさらにList
import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String ns = sc.nextLine(); String[] h = ns.split(" "); List<Node> list = new ArrayList<>(); list.add(new Node(0)); int N = Integer.parseInt(h[0]); int Q = Integer.parseInt(h[1]); for (int i = 1; i <= N; i++) { list.add(new Node(i)); } //ノードの連結部分の処理 for (int i = 0; i < N - 1; i++) { String in = sc.nextLine(); String[] inputs = in.split(" "); int a = Integer.parseInt(inputs[0]); int b = Integer.parseInt(inputs[1]); list.get(a).addChild(list.get(b)); } for (int i = 1; i <= Q; i++) { String input = sc.nextLine(); String[] inputs = input.split(" "); int nodeId = Integer.parseInt(inputs[0]); int addCount = Integer.parseInt(inputs[1]); Node node = list.get(nodeId); node.addCount(addCount); } list.remove(0); String result = list.stream().map(n -> String.valueOf(n.count)).collect(Collectors.joining(" ")); System.out.println(result); } static class Node { int id; long count; List<Node> children = new ArrayList<Main.Node>();; Node(int id) { this.id = id; this.count = 0; } public void addChild(Node node) { children.add(node); } public void addCount(long count) { this.count += count; for (Node node : this.children) { node.addCount(count); } } @Override public String toString() { return String.valueOf(this.id) + this.count; } } }