其实,很早很早之前学习c语言教程的时候,就见过这个问题,当时只觉得很复杂,好麻烦,而且在之后学习算法的时候又碰到了,还是那样,就一直没写过。
不过,经过近期的面试的打击,发觉正是这种态度害了自己,越是觉得不太清晰的就一定要弄的彻底明白,否则一知半解,不如不懂,要懂就得懂的彻底。因此,
在今天看一本书上面出现这个题目的时候,终于自己下定决心写出来这个程序,本来打算用c写的,不过感觉c有些处理没有stl中的数据结构来的方便,就用c++写了,
以下是代码:
#include<iostream>
#include<vector>
using namespace std;
int a[8][8] = {
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};
int sum = 0;
typedef struct node{
int x;
int y;
}position;
void find_solution(vector<position> &v_);
bool right_position(const vector<position> &v_, int y_);
void display(const vector<position> &v_);
int main()
{
vector<position> solution;
find_solution(solution);
cout << "Total " << sum << " solutions" << endl;
return 0;
}
void find_solution(vector<position> &v_)
{
for(int j = 0; j < 8; j++)
{
if(true == right_position(v_, j))
{
position tmp;
tmp.x = v_.size();
tmp.y = j;
a[tmp.x][tmp.y] = 1;
v_.push_back(tmp);
}
else //第一次的时候,居然还是忘记了这么一句,段错误不断呀。。。
{
continue;
}
if(8 == v_.size())
{
display(v_);
sum++;
}
else
{
find_solution(v_); //递归
}
position pos = v_.back(); //回溯
a[pos.x][pos.y] = 0;
v_.pop_back();
}
}
bool right_position(const vector<position> &v_, int y_)
{
int i, j;
i = v_.size();
j = y_;
for(int q = 0; q < 8; q++) //这部分应该还可以优化,不过本来耗时也不多,才8*8的数组
{
for( int p = 0; p < 8; p++)
{
if(1 == a[q][p])
{
if(i == q || j == p || (i - q) == (j - p) || (i - q) == (p - j))
{
return false;
}
}
}
}
return true;
}
void display(const vector<position> &v_)
{
cout << "{ ";
for(vector<position>::const_iterator it = v_.begin(); it != v_.end(); ++it)
{
cout << "(" << it->x << "," << it->y << ") ";
}
cout << "}\n";
}
写完之后,发现其中的递归与回溯也就是那么回事,其实很清晰,平常自己面对感觉复杂的题目就是不去动手了,结果产生害怕的心理,真心不应该呀。
看来找实习的失败经历,还是有用的~