1. 程式人生 > >棋盤覆蓋問題 分治和棧實現

棋盤覆蓋問題 分治和棧實現

#include<iostream>
#include<math.h>
#include <algorithm>
#include<string>
#include<stack>
using namespace std;

int chessboard[1024][1024];
int type = 0;
int N;
struct chess {
	int x;
	int y;
	int k;
	int cx;
	int cy;
};
stack <chess> chessStack;

void Print(int
k) { int n = pow(2, k); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { printf("%5d", chessboard[i][j]); } printf("\n"); } printf("\n"); } //用於給結構體賦值 void Assign(int x, int y, int k, int cx, int cy, chess & c) { c.x = x; c.y = y; c.cx = cx; c.cy = cy; c.k = k; } void
ChessViaStack() { while (!chessStack.empty()) { chess ctemp; chess c = chessStack.top(); chessStack.pop(); int x = c.x, y = c.y, k = c.k, cx = c.cx, cy = c.cy; int n = pow(2, k); type++; if (n < 2) { type--; } //已被覆蓋的座標在左上方 else if ((cx < x + n / 2) && (cy < y +
n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2] = type; chessboard[x + n / 2][y + n / 2 - 1] = type; chessboard[x + n / 2][y + n / 2] = type; Assign(x, y, k - 1, cx, cy, ctemp); chessStack.push(ctemp); Assign(x, y + n / 2, k - 1, x + n / 2 - 1, y + n / 2, ctemp); chessStack.push(ctemp); Assign(x + n / 2, y, k - 1, x + n / 2, y + n / 2 - 1, ctemp); chessStack.push(ctemp); Assign(x + n / 2, y + n / 2, k - 1, x + n / 2, y + n / 2, ctemp); chessStack.push(ctemp); } //左下 else if ((cx >= x + n / 2) && (cy < y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2 - 1] = type; chessboard[x + n / 2 - 1][y + n / 2] = type; chessboard[x + n / 2][y + n / 2] = type; Assign(x + n / 2, y, k - 1, cx, cy, ctemp); chessStack.push(ctemp); Assign(x, y, k - 1, x + n / 2 - 1, y + n / 2 - 1, ctemp); chessStack.push(ctemp); Assign(x, y + n / 2, k - 1, x + n / 2 - 1, y + n / 2, ctemp); chessStack.push(ctemp); Assign(x + n / 2, y + n / 2, k - 1, x + n / 2, y + n / 2, ctemp); chessStack.push(ctemp); } //右上 else if ((cx < x + n / 2) && (cy >= y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2 - 1] = type; chessboard[x + n / 2][y + n / 2 - 1] = type; chessboard[x + n / 2][y + n / 2] = type; Assign(x, y + n / 2, k - 1, cx, cy, ctemp); chessStack.push(ctemp); Assign(x, y, k - 1, x + n / 2 - 1, y + n / 2 - 1, ctemp); chessStack.push(ctemp); Assign(x + n / 2, y, k - 1, x + n / 2, y + n / 2 - 1, ctemp); chessStack.push(ctemp); Assign(x + n / 2, y + n / 2, k - 1, x + n / 2, y + n / 2, ctemp); chessStack.push(ctemp); } //右下 else if ((cx >= x + n / 2) && (cy >= y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2 - 1] = type; chessboard[x + n / 2 - 1][y + n / 2] = type; chessboard[x + n / 2][y + n / 2 - 1] = type; Assign(x + n / 2, y + n / 2, k - 1, cx, cy, ctemp); chessStack.push(ctemp); Assign(x, y, k - 1, x + n / 2 - 1, y + n / 2 - 1, ctemp); chessStack.push(ctemp); Assign(x, y + n / 2, k - 1, x + n / 2 - 1, y + n / 2, ctemp); chessStack.push(ctemp); Assign(x + n / 2, y, k - 1, x + n / 2, y + n / 2 - 1, ctemp); chessStack.push(ctemp); } } } void RecursiveChess(int x, int y, int k, int cx, int cy) { //Print(k); int n = pow(2, k); type++; if (n < 2) { type--; return; } //已被覆蓋的座標在左上方 else if ((cx < x + n / 2) && (cy < y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2] = type; chessboard[x + n / 2][y + n / 2 - 1] = type; chessboard[x + n / 2][y + n / 2] = type; RecursiveChess(x, y, k - 1, cx, cy); RecursiveChess(x, y + n / 2, k - 1, x + n / 2 - 1, y + n / 2); RecursiveChess(x + n / 2, y, k - 1, x + n / 2, y + n / 2 - 1); RecursiveChess(x + n / 2, y + n / 2, k - 1, x + n / 2, y + n / 2); } //左下 else if ((cx >= x + n / 2) && (cy < y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2 - 1] = type; chessboard[x + n / 2 - 1][y + n / 2] = type; chessboard[x + n / 2][y + n / 2] = type; RecursiveChess(x + n / 2, y, k - 1, cx, cy); RecursiveChess(x, y, k - 1, x + n / 2 - 1, y + n / 2 - 1); RecursiveChess(x, y + n / 2, k - 1, x + n / 2 - 1, y + n / 2); RecursiveChess(x + n / 2, y + n / 2, k - 1, x + n / 2, y + n / 2); } //右上 else if ((cx < x + n / 2) && (cy >= y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2 - 1] = type; chessboard[x + n / 2][y + n / 2 - 1] = type; chessboard[x + n / 2][y + n / 2] = type; RecursiveChess(x, y + n / 2, k - 1, cx, cy); RecursiveChess(x, y, k - 1, x + n / 2 - 1, y + n / 2 - 1); RecursiveChess(x + n / 2, y, k - 1, x + n / 2, y + n / 2 - 1); RecursiveChess(x + n / 2, y + n / 2, k - 1, x + n / 2, y + n / 2); } //右下 else if ((cx >= x + n / 2) && (cy >= y + n / 2)) { //再覆蓋三個棋子 chessboard[x + n / 2 - 1][y + n / 2 - 1] = type; chessboard[x + n / 2 - 1][y + n / 2] = type; chessboard[x + n / 2][y + n / 2 - 1] = type; RecursiveChess(x + n / 2, y + n / 2, k - 1, cx, cy); RecursiveChess(x, y, k - 1, x + n / 2 - 1, y + n / 2 - 1); RecursiveChess(x, y + n / 2, k - 1, x + n / 2 - 1, y + n / 2); RecursiveChess(x + n / 2, y, k - 1, x + n / 2, y + n / 2 - 1); } } int main() { int k,cx, cy; while (cin >> k) { memset(chessboard, 0, 1024 * 1024 * sizeof(int)); cin >> cx >> cy; N = pow(2, k); type = 0; chessboard[cx][cy] = -1; RecursiveChess(0, 0, k, cx, cy); /* *棧實現 chess c; Assign(0, 0, k, cx, cy, c); chessStack.push(c); ChessViaStack(); */ Print(k); } system("pause"); return 0; }