【Java】【Math】atan2メソッドなどMathクラスについて
最近下の2問を解きました。
Prime Factorize
Counter Clockwise
2問ともそこそこ時間が掛かってプロコンどころではない実力ですが…。
A問題は動いたのですが、B問題はフォーマット違いだったり結果違いだったりで結局
提出には至りませんでした。
学んだことたちをまとめます。
Scannerクラス
・next()で読むと空白(Javaデフォルトの区切り文字)で区切られてその行の残りは捨てられてしまう。
・nextLine()で読んでいたが一度Scannerオブジェクトをクローズすると後から別のScannerオブジェクトを作っても動作しない。
・入出力系のソースは非常にややこしいため、完全に理解しようとは思わない。時間のある時にじっくり。
Mathクラス
・abs、atan2、hypot、PIなど学部生の演習問題に使えそうなメソッドがたくさん。知ってたもん勝ち。
・atan2は、座標→x軸とのなす角の変換をしてくれる。引数の順番はyが先のため注意。ソース読んでもnativeだったため理由は不明。
・atan2の出力はpi~-piなので(180 / pi)を書けて弧度法に直すと多少直感的に使える。
その他
・staticインポートは超便利。
・コードが汚いし、なによりテストができていない。JUnit切実!!
Prime Factorize
Counter Clockwise
本日書いたコードやらなんやらです。
Prime Factorize
import static java.lang.Math.*; import java.util.ArrayList; import java.util.Scanner; public class Main { public static boolean itIsPrime(int a) { if (a == 1) { return false; } for (int i = 2; i <= sqrt(a); i++) { if ((a % i) == 0) { return false; } } return true; } public static ArrayList<Integer> primeFactorize(int a) { ArrayList<Integer> result = new ArrayList<Integer>(); result.add(a); if (a == 1) { result.add(a); return result; } int forDecompose = a; int factor = 2; while (factor <= forDecompose) { if (itIsPrime(forDecompose)) { result.add(forDecompose); return result; } if ((forDecompose % factor) == 0) { forDecompose = forDecompose / factor; result.add(factor); continue; } factor++; } return result; } public static String printFactrize(ArrayList<Integer> factrized) { String s = ""; s += factrized.remove(0) + ":"; for (int i : factrized) { s += " " + i; } return s; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int input = sc.nextInt(); sc.close(); ArrayList<Integer> aaaa = primeFactorize(input); System.out.println(printFactrize(aaaa)); } }
Counter Clockwise
import static java.lang.Math.*; import java.util.ArrayList; import java.util.Scanner; public class Main { static Scanner sc = new Scanner(System.in); public static ArrayList<String> scanLine(int a /* times */){ ArrayList<String> scaned = new ArrayList<String>(); for (int i = 0; i < a; i++){ scaned.add(sc.nextLine()); } return scaned; } public static ArrayList<String> scanAllLine(){ ArrayList<String> scaned = scanLine(2); int readCount = Integer.parseInt(scaned.get(1)); scaned.addAll(scanLine(readCount)); return scaned; } private static double getTheta(int x, int y){ return (atan2(y, x) * (180.0 / Math.PI) + 360.0) % 360.0; } private static String getStatus(int x1, int y1, int x2, int y2){ final String[] MESSAGE = { "COUNTER_CLOCKWISE", "CLOCKWISE", "ONLINE_BACK", "ONLINE_FRONT", "ON_SEGMENT" }; // if (x2 == 0 && y2 == 0) return MESSAGE[4]; double theta1 = getTheta(x1, y1); double theta2 = getTheta(x2, y2); double r1 = hypot(x1, y1); double r2 = hypot(x2, y2); if (theta1 == theta2){ return r1 <= r2 ? MESSAGE[3] : MESSAGE[4]; }else if(abs(theta1 - theta2) == 180.0){ return MESSAGE[2]; }else if(0.0 <= theta1 && theta1 < 180.0){ return (-180.0 < (theta1 - theta2) && (theta1 - theta2) < 0.0) ? MESSAGE[0] : MESSAGE[1]; }else{ return (180.0 > (theta1 - theta2) && (theta1 - theta2) > 0.0) ? MESSAGE[1] : MESSAGE[0]; } } private static void output(){ ArrayList<String> scaned = scanAllLine(); String tmp = scaned.remove(0); int x0 = Integer.parseInt(tmp.split(" ")[0]); int y0 = Integer.parseInt(tmp.split(" ")[1]); int x1 = Integer.parseInt(tmp.split(" ")[2]); int y1 = Integer.parseInt(tmp.split(" ")[3]); int a0 = x1 - x0; int b0 = y1 - y0; int x2 = 0; int y2 = 0; int a1 = 0; int b1 = 0; scaned.remove(0); ArrayList<String> output = new ArrayList<String>(); for (String s : scaned){ x2 = Integer.parseInt(s.split(" ")[0]); y2 = Integer.parseInt(s.split(" ")[1]); a1 = x2 - x0; b1 = y2 - y0; output.add(getStatus(a0, b0, a1, b1)); } String tmp2 = ""; for (String s : output){ System.out.println(s); } } public static void main(String[] args) { output(); sc.close(); } }