棋盤覆蓋問題 分治和棧實現
阿新 • • 發佈:2018-11-08
#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;
}