プログラミングしたい日記

いつもプログラミングとか音楽聞いてたりする人の日記です

これから毎週日曜日AOJ2題づつやっていこうと思います

どうも。大学入学したwintermaplesです。大学エンジョイしてます。

最近数学的なプログラミングあんまやってない気がするのでAOJやるの習慣づけようかなーって思ってます。
ちなみに、既に少しだけやっちゃってます。
ルールは以下の通り

  • 毎週日曜日にAOJの問題を2題解く
  • 解説とソースコードを書く
  • やらなかったら来週に持ち越し。最大6題
  • Volume0から順番に解いていく
  • 使える言語の中からできるだけランダムに使う
  • 自前のライブラリみたいなのは使用OK。それ以外はデフォルトで入っているもののみ
  • ただし初回は土曜日(この記事を書いた日)

こんな感じでやっていきます。

じゃあ早速

AOJ Volume 0 Q4

Simultaneous Equation | Aizu Online Judge

問題の概要

2元1次連立方程式を解く。ただし、小数点第4位で四捨五入。解なしは考慮しない。

つまづいた所
double x = (double) (c * e - b * f) / (a * e - b * d);

ここint/intになってて、結果もintにするように最初してたからWrong Answer勃発してた。
それ以外は特になし。ちなみに、最初まともに計算して解の公式作ってた。調べたら一般性のある解の公式あるじゃんっていう。

ソース
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Scanner;

/**
 * Created by wintermaples on 2017/04/29.
 */
public class Main {

  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String read;
    while (scanner.hasNext()) {
      read = scanner.nextLine();
      //1行を読み込んでint配列に
      int[] variables = Arrays.stream(read.split(" "))
          .mapToInt(s -> Integer.parseInt(s))
          .toArray();

      //わかりやすいようにそれぞれ変数に格納
      int a = variables[0];
      int b = variables[1];
      int c = variables[2];
      int d = variables[3];
      int e = variables[4];
      int f = variables[5];

      //解はクラメルの公式で一発
      double x = (double) (c * e - b * f) / (a * e - b * d);
      double y = (double) (a * f - c * d) / (a * e - b * d);
      BigDecimal xBD = new BigDecimal(x);
      BigDecimal yBD = new BigDecimal(y);
      xBD = xBD.setScale(3, BigDecimal.ROUND_HALF_UP);
      yBD = yBD.setScale(3, BigDecimal.ROUND_HALF_UP);

      //3桁にまとめて出力
      System.out.println(
          String.format("%.3f", xBD) + " " + String.format("%.3f", yBD)
      );

    }
  }

}

AOJ Volume 0 Q10

Circumscribed Circle of a Triangle | Aizu Online Judge

問題の概要

3点の座標が与えられ、それらが作る三角形の外接円の座標と半径を求める。

つまづいた所

そもそもpythonに慣れてない。標準入力から調べんとよーわからんかった。
あと、中心の座標の一般解求めるのめんどくさかった。
python3だと四捨五入がおかしいとか出てきたけど提出したら通ったから問題ない(多分)

解説

中心の座標は2元1次連立方程式に帰着したので、さっきの解の公式にぶちこんで、フォーマット&出力して終わり。
ちなみに、中心の座標の解px, pyは次で表される。

{ \displaystyle
a_1 := 2(x_2 - x_1)\\
b_1 := 2(y_2 - y_1)\\
c_1 := x_2^2 + y_2^2 - x_1^2 - y_1^2\\
a_2 := 2(x_3 - x_1)\\
b_2 := 2(y_3 - y_1)\\
c_2 := x_3^2 + y_3^2 - x_1^2 - y_1^2\\
a_1px + b_1py = c_1\\
a_2px + b_2py = c_2\\
Solution:\\
px=\frac{(y_3-y_1)(x_2^2 + y_2^2 - x_1^2 - y_1^2)-(y_2-y_1)(x_3^2 + y_3^2 - x_1^2 - y_1^2)}{2(x_2-x_1)(y_3-y_1)-2(x_3-x_1)(y_3-y_1)}\\
py=\frac{(x_2-x_1)(x_3^2 + y_3^2 - x_1^2 - y_1^2)-(x_3-y_1)(x_2^2 + y_2^2 - x_1^2 - y_1^2)}{2(x_2-x_1)(y_3-y_1)-2(x_3-x_1)(y_3-y_1)}\\
}

カオスだなこりゃ

ソース
import math

n = int(input())

for i in range(n):
	x1, y1, x2, y2, x3, y3 = map(float, input().split()) # Get variables
	a = 2 * (x2 - x1)
	b = 2 * (y2 - y1)
	c = math.pow(x2, 2) + math.pow(y2, 2) - math.pow(x1, 2) - math.pow(y1, 2)
	d = 2 * (x3 - x1)
	e = 2 * (y3 - y1)
	f = math.pow(x3, 2) + math.pow(y3, 2) - math.pow(x1, 2) - math.pow(y1, 2)
	px = (c * e - b * f) / (a * e - b * d)
	py = (a * f - c * d) / (a * e - b * d)
	r = math.sqrt(math.pow(x1 - px, 2) + math.pow(y1 - py, 2))
	print('{:.3f}'.format(px) + ' ' + '{:.3f}'.format(py) + ' ' + '{:.3f}'.format(r))
CSS Design created by satotaka99. Thankyou.