Board Game score

每一个格子代表一种地形,同时格子上可能有多个皇冠或没有。要求是计算一个score,score的计算方式是,先找到彼此连接的同种地形,
记录该块土地的面积(即几个格子)和该块土地上的总皇冠数,再对所有的面积和皇冠数之积,进行累加。表达式大概就是score = area0 * crown0 + area1 * crown1 + area2 * crown2...

Union Find的经典案列。比一般的UF的解法多的就是这里多了一个Crown的数量。
解法的办法就是UF里面再建一个Crown的数组, Union的时候把crown的数量也Union在一起。
还是比较直接的,没什么好说的。
我写的时候出了两个bug,
1。 UF constructor里面忘了新建那几个数组了。
2。 UF Union的时候 我忘了判断是不是本来root就是相等的了。这时一定要退出,否则会出错。
看代码,长是长了一点, 不过都是基本操作呀
UF基本功要打好。

    public int calBoardGame(List input) {
        int N = input.size();
        int M = input.get(0).split(" ").length;
        char[][] board = new char[N][M];
        int[][] crowns = new int[N][M];
        for (int i = 0; i < N; i++) {
            String[] line = input.get(i).split(" ");
            for (int c = 0; c < M; c++) {
                board[i][c] = line[c].charAt(0);
                crowns[i][c] = line[c].charAt(1) - '0';
            }
        }
        UnionFind uf = new UnionFind(N * M, crowns);
        for (int row = 0; row < N; row++) {
            for (int col = 0; col < M; col++) {
                if (row > 0 && board[row - 1][col] == board[row][col]) {
                    uf.union(col + (row - 1) * M, col + (row) * M);
                }
                if (col > 0 && board[row][col - 1] == board[row][col]) {
                    uf.union(col - 1 + (row ) * M, col + (row) * M);
                }
            }
        }
        int sum = 0;
        for (int i = 0; i < N * M; i++) {
            if (uf.root(i) == i) {
                sum += uf.getWeight(i) * uf.getCrown(i);
            }
        }
        return sum;
    }
    class UnionFind{
        int[] ids;
        int[] weights;
        int[] crowns;
        public UnionFind(int n, int[][] crownBoard) {
            int N = crownBoard.length, M = crownBoard[0].length;
            ids = new int[N * M];
            weights = new int[N * M];
            crowns = new int[N * M];
            for (int r = 0; r < N; r++) {
                for (int c = 0; c < M; c++) {
                    ids[r * M + c] = r * M + c;
                    weights[r * M + c] = 1;
                    crowns[r * M + c] = crownBoard[r][c];
                }
            }
        }
        public int root(int id){
            if (ids[id] != id) {
                ids[id] = root(ids[id]);
            }
            return ids[id];
        }
        public void union(int id1, int id2) {
            int root1 = root(id1), root2 = root(id2);
            if (root1 == root2) return; //一定要检查,没查就错了
            if (weights[root1] >= weights[root2]) {
                ids[root2] = root1;
                weights[root1] += weights[root2];
                crowns[root1] += crowns[root2];
            } else {
                ids[root1] = root2;
                weights[root2] += weights[root1];
                crowns[root2] += crowns[root1];
            }

        }
        public int getWeight(int id) {
            return weights[id];
        }
        public int getCrown(int id) {
            return crowns[id];
        }
    }

你可能感兴趣的:(Board Game score)