Как я могу найти все решение и использовать backtracking без алгоритма X и dancing link в C++?
Я только что разработал программу о решении Пентомино. Однако я сталкиваюсь с некоторыми проблемами, используя алгоритм обратного отслеживания. Я использую Code:: Block для отладки. Когда я попытался вернуться. Я обнаружил, что функция removepuzzle работает не очень хорошо. Цикл for внутри не может работать нормально. Он будет пропускать, и я буду увеличивать каждый шаг. Кроме того, эта программа, похоже, может найти только одно решение. Как я могу изменить его, чтобы найти решения? Точно так же, как решения платы 5х12-это 1088. Огромное спасибо.
Что я уже пробовал:
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) { // complete your constructor 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'; } /* * Print the result F (first solution), L (last solution) and N (number of solutions) * as required in the output format. If there is no solution, print 'nil' to replace * the solution string. * * The function is called from main() when a puzzle is solved. * */ void output() const { /*for(int i=0; i<r_size; i++) { for(int j=0; j<c_size; j++) { cout << board[i][j]; } cout << endl; }*/ // dummy output 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'; } } /*for (int i=0; i<5; i++) { r = box.row + p.row[i]; c = box.col + p.col[i]; box.board[r][c] = '\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; } /* * Find all solutions having the 12 pentominoes touching the edges of the rectangle * box using backtracking algorithm. The first argument 'count' is used to track the * progress of your backtracking algorithm. Its actual use depends on how you model * the problem. */ 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)) { //box.r_temp = box.row; //box.c_temp = box.col; usedChar[count++] = p[i].puzzle; placePuzzle(p[i], box); //cout << p[i].puzzle << box.row << box.col << "\t"; 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'; //box.row = box.r_temp; //box.col = box.c_temp; removepuzzle(p[i], box); } } } /* * Driver program to test above functions against default test cases. * Input filename must be provided by command-line argument. * * **** DON'T modify this main function. **** */ int main(int argc, char** argv) { //ifstream fin(argv[1]); 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; // run and measure clock_t start = clock(); // create a box with specific dimension Box* box = new Box(row, col); solve(0, *box); // output result F, L and N box->output(); clock_t end = clock(); int time = (end - start) * 1000.0 / CLOCKS_PER_SEC; // output result T and S printf(" %d %d\n", time, SID); // clean memory for every test case delete box; } return 0; }