2013-02-27 3 views
0

Мне дана доска размером 2^k * 2^k, и одна из плиток случайно удалена, что делает ее недостаточной доской. Задача состоит в том, чтобы заполнить «тромины», которые представляют собой L-образную фигуру из 3-х плиток.алгоритм разделения и покоя

Процесс решения проблемы не слишком сложный. Если плата 2x2, то для ее заполнения требуется всего один тромбон. Для любого большего размера его нужно разделить на четверти (составление четырех досок размером 2^(к-1)), причем один тромино помещен в центр, так что каждый квадрант имеет один заполненный плиткой. После этого доска может быть рекурсивно заполнена до тех пор, пока каждая плитка не будет заполнена случайным цветным тромбином.

Моей главной проблемой является реализация кода. Мои навыки программирования на Java в целом довольно слабы, и у меня часто возникают проблемы с поиском места для начала. Единственная работа, которая должна быть выполнена, - это метод плитки в классе tiling, который принимает в качестве входных данных недостающую доску для плитки, строку и столбец, чтобы начать чередование, и количество заполняемых фрагментов. Это проблема домашней работы, поэтому я просто ищу руководство или место для начала - любая помощь будет очень признательна.

public class BoardViewer extends JFrame { 

private static final int WIDTH = 1024; 
private static final int HEIGHT = 768; 
private static final int OFFSET = 30; 

public static final int UPVERT = 1; 
public static final int DNVERT = 2; 
public static final int RHORIZ = 4; 
public static final int LHORIZ = 8; 
public static final int FILL = 16; 

private Color [][] board; 

public BoardViewer(DeficientBoard db) { 
    super(); 
    setSize(WIDTH + (OFFSET*2), HEIGHT + (OFFSET*2)); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setResizable(false); 

    board = db.getBoardColor(); 
} 

public void paint(Graphics g) { 
    super.paint(g); 

    int width = WIDTH/board[0].length; 
    int height = HEIGHT/board.length; 

    for (int r = 0; r < board.length; r++) 
     for (int c = 0; c < board[r].length; c++) { 
      g.setColor(board[r][c]); 

      int x = c*width + OFFSET; 
      int y = r*height + OFFSET + (OFFSET/2); 

      g.fillRect(x+1, y+1, width-1, height-1); 
     } 
} 

}

public class DeficientBoard { 

private int n; 
private Color board[][]; 

// The four rotations of the tile. 
// UL is XX 
//  X 
// UR is XX 
//  X 
// LL is X 
//  XX 
// LR is X 
//  XX 
public final int UL = 0; 
public final int UR = 1; 
public final int LL = 2; 
public final int LR = 3; 

/** 
* Create a 2^k x 2^k deficient board. 
* 
* @param k power 
*/ 
public DeficientBoard(int k) { 
    n = (int)Math.pow(2, k); 
    createBoard(Color.LIGHT_GRAY); 
} 

/** 
* Actually create an n x n deficient board. 
* 
* @param color background color 
*/ 
private void createBoard(Color color) { 
    board = new Color[n][n]; 
    for (int r = 0; r < board.length; r++) 
     for (int c = 0; c < board[0].length; c++) 
      board[r][c] = color; 

    int d_row = (int)(Math.random() * n); 
    int d_col = (int)(Math.random() * n); 
    board[d_row][d_col] = Color.BLACK; 
} 

/** 
* Given a row and column and shape based on that point 
* place a tromino of the given color. 
* 
* @param r row 
* @param c column 
* @param s shape (UL, UR, LL, LR) 
* @param theColor a Color 
*/ 
public void placeTromino(int r, int c, int s, Color theColor) { 
    if (s == UL) { 
     board[r][c] = theColor; 
     board[r][c+1] = theColor; 
     board[r+1][c] = theColor; 
    } else if (s == UR) { 
     board[r][c] = theColor; 
     board[r][c+1] = theColor; 
     board[r+1][c+1] = theColor; 
    } else if (s == LL) { 
     board[r][c] = theColor; 
     board[r+1][c] = theColor; 
     board[r+1][c+1] = theColor; 
    } else { 
     board[r+1][c] = theColor; 
     board[r+1][c+1] = theColor; 
     board[r][c+1] = theColor; 
    } 
} 

/** 
* Get the 2^k x 2^k board. 
* 
* @return the Color board. 
*/ 
public Color[][] getBoardColor() { 
    return board; 
} 

/** 
* Find and return the deficient row. 
* 
* @param row row 
* @param col column 
* @param sz size of the baord 
* @return the row the deficient block is located 
*/ 
public int getDeficientRow(int row, int col, int sz) { 

    for (int r = row; r < (row + sz); r++) 
     for (int c = col; c < (col + sz); c++) 
      if (board[r][c] != Color.LIGHT_GRAY) 
       return r; 

    return -1; 
} 

/** 
* Find and return the deficient column. 
* 
* @param row row 
* @param col column 
* @param sz size of the baord 
* @return the row the deficient block is located 
*/ 
public int getDeficientCol(int row, int col, int sz) { 
    for (int r = row; r < (row + sz); r++) 
     for (int c = col; c < (col + sz); c++) 
      if (board[r][c] != Color.LIGHT_GRAY) 
       return c; 

    return -1; 
} 

/** 
* Get the size of the deficient board. 
* 
* @return the size 
*/ 
public int getSize() { 
    return n; 
} 

/** 
* Display information about the deficient board. 
*/ 
public String toString() { 
    return ("Deficient board of size " 
      + n + "x" + n 
      + " with position missing at (" 
      + getDeficientRow(0, 0, n) + "," + getDeficientCol(0, 0, n) +")."); 
} 

}

public class Tiling { 

private static Color randColor() { 
    int r = (int)(Math.random() * 256); 
    int g = (int)(Math.random() * 256); 
    int b = (int)(Math.random() * 256); 

    return new Color(r, g, b); 
} 

public static void tile(DeficientBoard db, int row, int col, int n) { 


} 

public static void main(String[] args) { 

    DeficientBoard db = new DeficientBoard(3); 
    System.out.println(db); 

    tile(db, 0, 0, db.getSize()); 

    BoardViewer bv = new BoardViewer(db); 
    bv.setVisible(true); 

} 

}

ответ

-1

Ну это несколько сложнее из проблемы решить. Тем не менее, я бы сказал, что у вас есть навыки, учитывая, сколько кода вы написали, поэтому я не был бы уверен в этом.

У меня нет полного решения, но я думаю, что если вы начнете с снятой плитки и поместите тромины по обе стороны от нее. Затем продолжайте наносить тромины по обе стороны от последних троминов. Вы «засыпаете» тромини, которую вы последний раз разместили на доске. Как только вы сделаете это до края доски. Все, что осталось, - это места в форме тромбона. Вот пример того, что я имею в виду (Х выпавший плитка т.е. зазор, Y являются trominos):

_ _ _ _ 
|_|_|_|_| 
|_|Y|Y|_| 
|_|Y|X|Y| 
|_|_|Y|Y| 

_ _ _ _ 
|Y|Y|_|_| 
|Y|Y|Y|_| 
|_|Y|X|Y| 
|_|_|Y|Y| 

После того, как доска заполнена до краев вы можете существенно начать падать trominos как бомбы на остальных доски. У меня есть ощущение, что здесь есть образец, где вы заполняете диагональные тромины, одновременно заполняя вторую часть, которая повторяется. Но если вы не можете найти это, тогда создайте рекурсивную подпрограмму, которая переместит промежуток к краям, а затем перейдет к добавлению троминов в диагональные узоры. Подсказка: вам нужно сделать переход только в первом стеке стека.

Удачи.

+0

-1, извините. Ваш предложенный алгоритм значительно уступает тому, который описывает OP во втором абзаце вопроса. Я не понимаю, почему вы предлагаете это, если только вы полностью не поняли вопрос OP. Re: «Я бы сказал, что у вас есть навыки, данные о том, сколько кода вы написали»: если я правильно понял вопрос, он еще не написал * никакого * кода; скорее, размещенный код - это то, что было поставлено как часть проблемы с домашним заданием, а фактическое назначение - реализовать 'Tiling.tile'. – ruakh

+0

Ну, я сказал, что у меня не было полного решения, и я прочитал сообщение, и нет никакого упоминания о том, кто автор кода. Алгоритм описанного ОП не содержит достаточно подробностей, как он решает заполнить тромины, или тот факт, что вы должны рекурсивно делить его на 4x4 и решать их, а не 2x2. Поэтому я считаю, что «значительно уступающий» немного драматичен, поскольку он не был полностью описан. – chubbsondubs

1

В общем, когда рекурсивная функция реализует алгоритм разделяй и властвуй, он должен обрабатывать два основных случая:

  • базового сценария. Это тот случай, когда вы закончили разделение, и вам нужно немного победить. В вашем задании базовый случай - это случай, когда n = 2, и в этом случае вам просто нужно найти, какая из четырех плиток отсутствует/окрашена (с использованием DefectiveBoard.getDeficientRow и DefectiveBoard.getDeficientCol) и добавьте соответствующий триомино для покрытия другие три плитки.
  • рекурсивный чехол. Это тот случай, когда вы не сделали деление, поэтому вам нужно разделить (т., recurse) и (в зависимости от алгоритма), возможно, потребуется немного поработать до или после рекурсии. В вашем назначении, рекурсивный случай является случай, когда п> 2. В этом случае вам нужно сделать две вещи:
    • Найти, какой из четырех квадрантов имеет недостающий/окрашенные плитки, а также добавить соответствующий triomino для покрытия одной плитки из каждого из трех других квадрантов.
    • Recurse, называя себя четыре раза (по одному для каждого квадранта).

Хорошая отправная точка, чтобы написать «Это базовый вариант?» проверить и реализовать базовый регистр.

После этого, если вы не видите, как написать рекурсивный случай, один подход к временно написать «один над основанием» случай (п = 4), и посмотреть, если вы можете обобщить Это. Если нет, вы можете затем временно написать «два над основанием» (n = 8) и так далее. (Как только у вас будет работать ваш рекурсивный алгоритм, вы удалите эти особые случаи, так как они полностью покрыты общим рекурсивным случаем.)