计算使用K颜色为N * M网格着色的方法数

时间:2014-01-18 13:50:21

标签: c++ algorithm

我想问你如何计算使用K颜色为N * M网格着色的方法的数量。网格中的相邻方块应具有不同的颜色。如果正方形共享边缘,则它们被认为是相邻的。有没有快速的算法呢?

1 个答案:

答案 0 :(得分:1)

注意:我假设我们没有使用每种颜色。如果我们这样做,可以轻松应用其他检查。

以下是一些可以解决您问题的代码(我认为)......它使用强力/回溯算法。这是3种颜色的输出,2乘3网格。它打印出它找到的每个组合。对于这个输入,答案是54。

Enter number of colors: 3
Enter number of rows: 2
Enter number of columns: 3
121
212

121
213

123
212

121
232

123
231

123
232

131
212

131
213

132
213

121
312

121
313

123
312

131
312

131
313

132
313

131
323

132
321

132
323

212
121

212
123

213
121

212
131

213
131

213
132

231
123

232
121

232
123

212
321

212
323

213
321

231
312

231
313

232
313

231
323

232
321

232
323

312
121

312
123

313
121

312
131

313
131

313
132

321
132

323
131

323
132

312
231

313
231

313
232

321
212

321
213

323
212

321
232

323
231

323
232

There are 54 different combinations of 3 colors.

这是一个Java代码:

import java.util.*;

public class ColorChoices
{
    int[][] grid;
    int numberOfColors;
    int numberOfRows;
    int numberOfColumns;
    int numberOfCombinations;

    public static void main(String[] args)
    {
        ColorChoices solution = new ColorChoices();
        solution.begin();

    }

    void begin()
    {
        numberOfCombinations = 0;
        Scanner consoleInput = new Scanner(System.in);
        System.out.print("Enter number of colors: ");
        numberOfColors = consoleInput.nextInt();
        System.out.print("Enter number of rows: ");
        numberOfRows = consoleInput.nextInt();
        System.out.print("Enter number of columns: ");
        numberOfColumns = consoleInput.nextInt();
        grid = new int[numberOfRows][numberOfColumns];

        solve(0, 0);

        System.out.println("There are " + numberOfCombinations + " different combinations of " + numberOfColors + " colors.");
    }

    void solve(int r, int c)
    {
        for(int i = 1; i <= numberOfColors; i++)
        {   
            if(valid(r, c, i))
            {
                grid[r][c] = i;
                if(r == numberOfRows - 1 && c == numberOfColumns - 1) 
                {
                    printBoard();
                    numberOfCombinations++;
                }
                else if(r == numberOfRows - 1) solve(0, c + 1);
                else solve(r + 1, c);
            }
        }
        grid[r][c] = 0;
    }

    boolean valid(int r, int c, int n)
    {
        return(leftOK(r, c, n) && rightOK(r, c, n) &&  topOK(r, c, n) &&  bottomOK(r, c, n));
    }

    boolean leftOK(int r, int c, int n)
    {
        if(c == 0) return true;
        if(grid[r][c - 1] != n) return true;
        return false;
    }

    boolean rightOK(int r, int c, int n)
    {
        if(c == numberOfColumns - 1) return true;
        if(grid[r][c + 1] != n) return true;
        return false;
    }

    boolean topOK(int r, int c, int n)
    {
        if(r == 0) return true;
        if(grid[r - 1][c] != n) return true;
        return false;
    }

    boolean bottomOK(int r, int c, int n)
    {
        if(r == numberOfRows - 1) return true;
        if(grid[r + 1][c] != n) return true;
        return false;
    }

    void printBoard()
    {
        for(int i = 0; i < numberOfRows; i++)
        {
            for(int j = 0; j < numberOfColumns; j++)
            {
                System.out.print(grid[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }
}