読者です 読者をやめる 読者になる 読者になる

丸三角四角

IT業界にしがみつく新人SEが立派なプログラマになろうともがく奮闘記

【Java】宝探し

今回の問題は、お宝の場所が街の中心から北~m、東~mの位置にあるかを求める問題です。

入力は前に進む方向と右に回る角度が与えられ、「0,0」が与えられたら座標を出力します。この問題で必要な知識として、sinとcosの式を知っておく必要があります。

三角形ABCの場合
    AB^2 + BC^2 = AC^2が成り立っている場合
    座標Aが(x,y)である場合
    座標Cは(AC * cosθ + x, AC * sinθ + y)が成り立つ。

上記を踏まえて以下コードです。

import static java.lang.Double.parseDouble;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.toRadians;
import static java.lang.System.out;
import volume0.BaseExe;

public class TreasureHunt extends BaseExe {

    public static void main(String[] args) {
        new TreasureHunt().exeSysIn();
    }

    @Override
    protected void execute() throws Exception {
        double ax = 0;
        double ay = 0;
        double run = 0;
        double deg = 90;
        while (judgeInData()) {
            if ("0,0".equals(getInData()))
                break;
            String[] inDataList = getInData().split(",");
            run = parseDouble(inDataList[0]);
            ax = getPX(run, deg, ax);
            ay = getPY(run, deg, ay);
            deg = getDeg(deg, parseDouble(inDataList[1]));
        }
        out.println((int) ax);
        out.println((int) ay);
    }

    private double getPX(double run, double deg, double ax) {
        return run * cos(toRadians(deg)) + ax;
    }

    private double getPY(double run, double deg, double ay) {
        return run * sin(toRadians(deg)) + ay;
    }

    private double getDeg(double deg, double plusDeg) {
        deg -= plusDeg;
        return (deg < 0.0) ? 360.0 + deg : (deg > 360.0) ? deg - 360.0 : deg;
    }
}

手探りで実装しましたが、上記のコードで期待通りの値を出力します。もっとより良い実装方法があればコメントいただけるとありがたいです。テストドライバの内容は以下になります。

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import volume0.BaseTest;

public class TreasureHuntTest extends BaseTest {

    private TreasureHunt th;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        th = new TreasureHunt();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void test0001() {
        th.exeFileIn("./data/volume0_0016/in.txt");
        assertOutList("./data/volume0_0016/out.txt");
    }
}

テストドライバ内で使用している「in.txt」・「out.txt」の内容は以下になります。

in.txt
56,65
97,54
64,-4
55,76
42,-27
43,80
87,-86
55,-6
89,34
95,5
0,0
out.txt
171
-302

今回の問題は以下にあります。

宝探し | Aizu Online Judge

アルゴリスムで困った時は、以下の本を参考にしてます。Javaに置き換えるのが少々難解ですが、、、

固有処理の基底クラスは以下の記事に記載していますので、参考にしてください。

dadainu.hateblo.jp

テストドライバで継承しているクラスは以下の記事に記載していますので、参考にしてみてください。

dadainu.hateblo.jp