N-queens問題(エイトクイーンズ問題)
火曜日提出のプログラミング課題の一つにN-queens問題が出題されました。わたしは出題されるまで知りませんでした。うふ。アルゴリズム・もんだいについては以下をご覧ください。
N-queens
私のごみコード
一生懸命書いたけど、classでの配列の初期化がうまくゆかずつまってしまいました。それを解決しようと配列コピーなんぞの苦肉の策がいっぱいあってごみ化しているコード。ゴミというか完全にメモリリークしている。
端的には参考にしてはいけないコード例。
#include <iostream> #include <algorithm> #include <cstring> using namespace std; class Queens{ public: Queens(int n); void calc(); int get_answer(); private: int boardSize; int answer; void set(int i ,int j,int matrix[]); int check(int i, int j,int matrix[]); }; Queens::Queens(int n){ this->answer = 0; this->boardSize = n; } void Queens::calc(){ int matrix[this->boardSize]; for(int i = 0; i<this->boardSize; i++){ for(int j =0; j <this->boardSize; j++ ){ matrix[j] = 0; } this->set(0,i,matrix); } } void Queens::set(int i, int j,int matrix[]){ int *new_matrix = new int[this->boardSize]; memcpy(new_matrix, matrix, this->boardSize*sizeof(int)); int checkMatrics = check(i,j,new_matrix); if(checkMatrics == -1){ // collision return; }else if(checkMatrics ==1){ // have not filled all matrix yet new_matrix[i] = j+1; if(i == this->boardSize-1){ this->answer++; return; }else{ for(int k = 0;k < this->boardSize; k++){ set(i+1,k, new_matrix); } } } return; } int Queens::check(int i, int j,int matrix[]){ /* cout <<" show;["; for(int p=0 ; p < this->boardSize;p++){ cout << matrix[p]<<","; } cout<<"]"; */ int r_up= i+1+j; int r_down = i-j+this->boardSize; for(int k=0; k <i; k++){ if( j == matrix[k]-1 || r_up == (k+1 + matrix[k] -1)|| r_down == (k+1 - matrix[k] +this->boardSize)){ // collision return -1; } } return 1; } int Queens::get_answer(){ return this->answer; } int main(int argc,char* agrc[]){ int n = 0; // size of board while(cin >> n){ Queens* newGame; newGame = new Queens(n); newGame->calc(); cout << newGame->get_answer() << endl; } return 0; }
もなえデバッガの吐いたコード
もなえデバッガとは私のコードを解読・解析して最適化もしくは修正してくれるデバッガです。もっと早く(解読不能になる前に)相談しろと怒られました。
完結でシンプル。素晴らしいコードをご堪能ください。
#include <iostream> #include <algorithm> #include <cstring> using namespace std; class Queens { public: Queens(int n); ~Queens(); void calc(); int get_answer(); private: int boardSize; int answer; int* matrix; void calc(int i); bool check(int i, int j); }; Queens::Queens(int n) { this->answer = 0; this->boardSize = n; this->matrix = new int[this->boardSize]; } Queens::~Queens() { delete[] this->matrix; } void Queens::calc() { this->answer = 0; calc(0); } void Queens::calc(int i) { if (i == this->boardSize) { cout <<" show_ans;["; for(int p = 0 ; p < this->boardSize; p++) { cout << this->matrix[p] <<","; } cout << "]" << endl; this->answer++; return; } for (int j = 0; j < this->boardSize; j++) { if (check(i, j)) { // success this->matrix[i] = j; calc(i + 1); } } } bool Queens::check(int i, int j) { /* cout <<" show;["; for(int p=0 ; p < this->boardSize;p++){ cout << matrix[p]<<","; } cout<<"]"; */ for (int k = 0; k < i; k++) { if (j == matrix[k] || (i + j) == (k + matrix[k]) || (i - j) == (k - matrix[k])) { // collision return false; } } return true; } int Queens::get_answer() { return this->answer; } int main(int argc, char* argv[]) { int n = 0; // size of board while(cin >> n){ Queens newGame(n); newGame.calc(); cout << newGame.get_answer() << endl; } return 0; }