I have just designed a program about solving the Pentominoes. However, I meet some problems using the backtracking algorithm. I'm using Code::Block to debug. When I tried to backtrack. I found that the removepuzzle function not working well. The for loop inside cannot run normally. It will skip and the i increment every step. Besides, this program seems like only can found one solution. How can I modify it to found the solutions? Just like the solutions of 5x12 board is 1088. Thank you so much.
What I have tried:
struct Pentominoes
{
int row[5];
int col[5];
int used;
char puzzle;
};
Pentominoes p[63] =
{
{{0,0,0,0,0},{0,1,2,3,4},-1,'I'},
{{0,1,2,3,4},{0,0,0,0,0},-1,'I'},
{{0,1,1,1,2},{0,-1,0,1,0},-1,'X'},
{{0,0,1,2,2},{0,1,0,-1,0},-1,'Z'},
{{0,1,1,1,2},{0,0,1,2,2},-1,'Z'},
{{0,0,1,2,2},{0,1,1,1,2},-1,'Z'},
{{0,1,1,1,2},{0,-2,-1,0,-2},-1,'Z'},
{{0,1,2,2,2},{0,0,0,1,2},-1,'V'},
{{0,0,0,1,2},{0,1,2,0,0},-1,'V'},
{{0,1,2,2,2},{0,0,-2,-1,0},-1,'V'},
{{0,0,0,1,2},{0,1,2,2,2},-1,'V'},
{{0,0,0,1,2},{0,1,2,1,1},-1,'T'},
{{0,1,1,1,2},{0,-1,-1,0,0},-1,'T'},
{{0,1,2,2,2},{0,0,-1,0,1},-1,'T'},
{{0,1,1,1,2},{0,0,1,2,0},-1,'T'},
{{0,1,1,2,2},{0,0,1,1,2},-1,'W'},
{{0,1,1,2,2},{0,-1,0,-2,-1},-1,'W'},
{{0,0,1,1,2},{0,1,1,2,2},-1,'W'},
{{0,0,1,1,2},{0,1,-1,0,-1},-1,'W'},
{{0,0,0,1,1},{0,1,2,0,2},-1,'U'},
{{0,0,1,2,2},{0,1,1,0,1},-1,'U'},
{{0,0,1,1,1},{0,2,0,1,2},-1,'U'},
{{0,0,1,2,2},{0,1,0,0,1},-1,'U'},
{{0,1,1,1,1},{0,0,1,2,3},-1,'L'},
{{0,1,2,3,3},{0,0,0,-1,0},-1,'L'},
{{0,0,0,0,1},{0,1,2,3,3},-1,'L'},
{{0,0,1,2,3},{0,1,0,0,0},-1,'L'},
{{0,0,1,2,3},{0,1,1,1,1},-1,'L'},
{{0,0,0,0,1},{0,1,2,3,0},-1,'L'},
{{0,1,2,3,3},{0,0,0,0,1},-1,'L'},
{{0,1,1,1,1},{0,-3,-2,-1,0},-1,'L'},
{{0,0,1,1,1},{0,1,-2,-1,0},-1,'N'},
{{0,1,1,2,3},{0,0,1,1,1},-1,'N'},
{{0,0,0,1,1},{0,1,2,-1,0},-1,'N'},
{{0,1,2,2,3},{0,0,0,1,1},-1,'N'},
{{0,0,1,1,1},{0,1,1,2,3},-1,'N'},
{{0,1,2,2,3},{0,0,-1,0,-1},-1,'N'},
{{0,0,0,1,1},{0,1,2,2,3},-1,'N'},
{{0,1,1,2,3},{0,-1,0,-1,-1},-1,'N'},
{{0,1,1,1,1},{0,-2,-1,0,1},-1,'Y'},
{{0,1,1,2,3},{0,-1,0,0,0},-1,'Y'},
{{0,0,0,0,1},{0,1,2,3,1},-1,'Y'},
{{0,1,2,2,3},{0,0,0,1,0},-1,'Y'},
{{0,0,0,0,1},{0,1,2,3,2},-1,'Y'},
{{0,1,1,2,3},{0,0,1,0,0},-1,'Y'},
{{0,1,1,1,1},{0,-1,0,1,2},-1,'Y'},
{{0,1,2,2,3},{0,0,-1,0,0},-1,'Y'},
{{0,1,1,1,2},{0,-1,0,1,1},-1,'F'},
{{0,0,1,1,2},{0,1,-1,0,0},-1,'F'},
{{0,1,1,1,2},{0,0,1,2,1},-1,'F'},
{{0,1,1,2,2},{0,0,1,-1,0},-1,'F'},
{{0,1,1,1,2},{0,-2,-1,0,-1},-1,'F'},
{{0,0,1,1,2},{0,1,1,2,1},-1,'F'},
{{0,1,1,1,2},{0,-1,0,1,-1},-1,'F'},
{{0,1,1,2,2},{0,-1,0,0,1},-1,'F'},
{{0,0,1,1,2},{0,1,0,1,1},-1,'P'},
{{0,0,0,1,1},{0,1,2,0,1},-1,'P'},
{{0,1,1,2,2},{0,0,1,0,1},-1,'P'},
{{0,0,1,1,1},{0,1,-1,0,1},-1,'P'},
{{0,0,1,1,1},{0,1,0,1,2},-1,'P'},
{{0,1,1,2,2},{0,-1,0,-1,0},-1,'P'},
{{0,0,0,1,1},{0,1,2,1,2},-1,'P'},
{{0,0,1,1,2},{0,1,0,1,0},-1,'P'}
};
char usedChar[12] = {'\0'};
class Box
{
public:
char **board;
int row = 0;
int col = 0;
int solCount = 0;
char c[12];
int r_size = 0;
int c_size = 0;
int r_temp = 0;
int c_temp = 0;
Box(int r, int c)
{
r_size = r;
c_size = c;
board = new char*[r];
for(int i=0; i<r; i++)
board[i] = new char[c];
for(int i=0; i<r; i++)
for(int j=0; j<c; j++)
board[i][j] = '\0';
}
void output() const
{
cout << "F " << "L " << "N " << solCount;
}
};
bool checkUnusedChar(Pentominoes p)
{
for(int i=0; i<12; i++)
{
if(p.puzzle == usedChar[i]) {
return false;
}
}
return true;
}
void updateRC(Box &box) {
bool empty = false;
for(int i=0; i<box.r_size; i++) {
for(int j=0; j<box.c_size; j++) {
if(box.board[i][j] == '\0') {
box.row = i;
box.col = j;
empty = true;
break;
}
}
if(empty)
break;
}
}
void placePuzzle(Pentominoes p, Box& box)
{
int r;
int c;
for (int i=0; i<5; i++) {
r = box.row + p.row[i];
c = box.col + p.col[i];
box.board[r][c] = p.puzzle;
}
}
void removepuzzle(Pentominoes p, Box box) {
int r = box.r_size;
int c = box.c_size;
int i=0;
int j=0;
for(i=0; i<r; i++) {
for(j=0; j<c; j++) {
if(box.board[i][j] == p.puzzle)
box.board[i][j] == '\0';
}
}
}
bool canPut(Pentominoes p, Box box) {
int r;
int c;
for (int i=0; i<5; i++) {
r = box.row + p.row[i];
c = box.col + p.col[i];
if(r < 0 || r >= box.r_size || c < 0 || c >= box.c_size || box.board[r][c] != '\0')
return false;
}
return true;
}
void solve(int count, Box& box)
{
if (count == 12)
{
box.solCount++;
return;
}
for(int i=0; i<63; i++)
{
if(checkUnusedChar(p[i]) && canPut(p[i], box))
{
usedChar[count++] = p[i].puzzle;
placePuzzle(p[i], box);
for(int a=0; a<box.r_size; a++) {
for(int b=0; b<box.c_size; b++) {
cout << box.board[a][b];
}
cout << endl;
}
cout << endl;
updateRC(box);
solve(count, box);
count--;
usedChar[count] = '\0';
removepuzzle(p[i], box);
}
}
}
int main(int argc, char** argv)
{
ifstream fin("a2_input.txt");
if (!fin)
{
cout << "Input file not found.";
exit(1);
}
int testcase = 0;
fin >> testcase;
for (int t = 0; t < testcase; t++)
{
int row, col;
fin >> row >> col;
clock_t start = clock();
Box* box = new Box(row, col);
solve(0, *box);
box->output();
clock_t end = clock();
int time = (end - start) * 1000.0 / CLOCKS_PER_SEC;
printf(" %d %d\n", time, SID);
delete box;
}
return 0;
}