中文
[BOJ 12850, Java]漫步主校园 2

[BOJ 12850, Java]漫步主校园 2

BOJ 12850,"在大学周围散步 2 "问题的 Java 解决方案

问题链接

boj 12850

分类

exponentiation_by_squaring, graph theory, maths, divide-and-conquer

描述

除法与征服(Devide and Conquer)

一种通过将难以解决的问题分解成更小问题来解决的算法。

这个问题可以通过绘制邻域矩阵来解决,并知道到达目的地的次数就是对邻域矩阵进行 n 次平方运算的次数。

这确实需要学习一些分而治之和矩阵运算的知识,但我认为这是一个结合了几个较低层次问题的合理难度。

解题代码

import java.io.*;
import java.util.*;

public class Main {

    public static HashMap<Integer, int[][]> matrixRecord = new HashMap<>();

    public static int[][] matrixCalculation(int[][] matrix1, int[][] matrix2) {
        /* 행렬 연산 함수 */

        int[][] resultArr = new int[8][8];

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {

                long sum = 0;

                for (int k = 0; k < 8; k++) {
                    sum += ((long) matrix1[i][k] * (long) matrix2[k][j]) % 1000000007;
                }

                resultArr[i][j] = (int) (sum % 1000000007);

            }
        }

        return resultArr;
    }

    public static int[][] matrixDivision(HashMap<Integer, int[][]> matrixInfo, int calculationCount) {
        /* 분할 정복을 통한 행렬 연산 함수 */

        int halfCount = calculationCount / 2;

        int[][] halfMatrix;
        int[][] otherHalfMatrix;

        // 기존 값이 존재할 경우 불러오기
        if (matrixInfo.containsKey(halfCount)) {
            halfMatrix = matrixInfo.get(halfCount);
        } else {
            halfMatrix = matrixDivision(matrixInfo, halfCount);
        }

        if (matrixInfo.containsKey(calculationCount - halfCount)) {
            otherHalfMatrix = matrixInfo.get(calculationCount - halfCount);
        } else {
            otherHalfMatrix = matrixDivision(matrixInfo, calculationCount - halfCount);
        }

        // 연산 후 행렬 반환
        int[][] calculationResult = matrixCalculation(halfMatrix, otherHalfMatrix);
        matrixInfo.putIfAbsent(calculationCount, calculationResult);

        return calculationResult;
    }

    public static void main(String[] args) throws IOException {

        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));

        int walkTime = Integer.parseInt(input.readLine());

        // 기본 행렬 및 본대 인접 행렬 선언
        int[][] baseMatrix = {
                {1, 0, 0, 0, 0, 0, 0, 0},
                {0, 1, 0, 0, 0, 0, 0, 0},
                {0, 0, 1, 0, 0, 0, 0, 0},
                {0, 0, 0, 1, 0, 0, 0, 0},
                {0, 0, 0, 0, 1, 0, 0, 0},
                {0, 0, 0, 0, 0, 1, 0, 0},
                {0, 0, 0, 0, 0, 0, 1, 0},
                {0, 0, 0, 0, 0, 0, 0, 1},
        };

        int[][] graph = {
                {0, 1, 1, 0, 0, 0, 0, 0},
                {1, 0, 0, 1, 0, 0, 0, 0},
                {1, 0, 0, 1, 1, 0, 0, 0},
                {0, 1, 1, 0, 1, 1, 0, 0},
                {0, 0, 1, 1, 0, 1, 1, 0},
                {0, 0, 0, 1, 1, 0, 1, 1},
                {0, 0, 0, 0, 1, 1, 0, 1},
                {0, 0, 0, 0, 0, 1, 1, 0},
        };

        // 해시맵에 초기값들 등록
        matrixRecord.put(0, baseMatrix);
        matrixRecord.put(1, graph);

        // 함수를 통해 분할정복 연산 실행
        matrixDivision(matrixRecord, walkTime);

        // 결과 출력
        output.write(Integer.toString(matrixRecord.get(walkTime)[7][7]));

        output.flush();
        output.close();

    }

}

댓글 작성

게시글에 대한 의견을 남겨 주세요.

댓글 0