POJ 3239解题报告

来源:互联网 发布:手机淘宝改背景颜色 编辑:程序博客网 时间:2024/06/08 20:18

传说中的N皇后问题,不过这道题只要求一组满足条件的解。如果按照通用的递归回溯算法会在n比较大的时候超时。所以有两个思路:

一是随机产生一个1~N的排列,如果满足条件(斜行不冲突),则输出;否则,交换两个元素的位置减少冲突,如果冲突可以减为0,则输出,否则重新生成随机排列。解法见这里。

另一种思路是构造解。见这里。可以以0ms过测试。原理见这里。(声明:我看不进去啊。。。只能知其然不知其所以然。。。)

代码如下:

#include <iostream>using namespace std;void print(int sol[], int n){for(int i = 0; i < n; ++i){cout<<sol[i];if(i == n - 1){cout<<endl;}elsecout<<" ";}}int main(){int sol[300];int n;while(true){cin>>n;if(n == 0)return 0;if(n % 6 != 2&& n % 6 != 3){int cnt = 0;for(int i = 2; i <= n; i += 2){sol[cnt] = i;cnt++;}for(int i = 1; i <= n; i += 2){sol[cnt] = i;cnt++;}}else{int k;if(n % 2 == 0)k = n / 2;elsek = (n - 1) / 2;if(n % 2 == 0 && k % 2 == 0){int cnt = 0;for(int i = k; i <= n; i += 2){sol[cnt] = i;cnt++;}for(int i = 2; i <= k - 2; i += 2){sol[cnt] = i;cnt++;}for(int i = k + 3; i <= n - 1; i += 2){sol[cnt] = i;cnt++;}for(int i = 1; i <= k + 1; i += 2){sol[cnt] = i;cnt++;}}else if(n % 2 == 1 && k % 2 == 0){int cnt = 0;for(int i = k; i <= n - 1; i += 2){sol[cnt] = i;cnt++;}for(int i = 2; i <= k - 2; i += 2){sol[cnt] = i;cnt++;}for(int i = k + 3; i <= n - 2; i += 2){sol[cnt] = i;cnt++;}for(int i = 1; i <= k + 1; i += 2){sol[cnt] = i;cnt++;}sol[cnt] = n;}else if(n % 2 == 0 && k % 2 == 1){int cnt = 0;for(int i = k; i <= n - 1; i += 2){sol[cnt] = i;cnt++;}for(int i = 1; i <= k - 2; i += 2){sol[cnt] = i;cnt++;}for(int i = k + 3; i <= n; i += 2){sol[cnt] = i;cnt++;}for(int i = 2; i <= k + 1; i += 2){sol[cnt] = i;cnt++;}}else{int cnt = 0;for(int i = k; i <= n - 2; i += 2){sol[cnt] = i;cnt++;}for(int i = 1; i <= k - 2; i += 2){sol[cnt] = i;cnt++;}for(int i = k + 3; i <= n - 1; i += 2){sol[cnt] = i;cnt++;}for(int i = 2; i <= k + 1; i += 2){sol[cnt] = i;cnt++;}sol[cnt] = n;}}print(sol, n);}return 0;}


原创粉丝点击