百练2754:八皇后

2754:八皇后

  • 查看
  • 提交
  • 统计
  • 提示
  • 提问
总时间限制: 
1000ms 
内存限制: 
65536kB
描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b 1b 2...b 8,其中b i为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
输出
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
样例输入
2
1
92
样例输出
15863724

84136275

不好意思,昨天食言了,没有更新博客,因为有点懒惰。今天9月1号了,后天即将返回大连,推免的整个征程只剩下最后不到一个月的时间,因此,行百里者半九十,一定要抓住最后的时间,拼上一把。

********************************************

八皇后问题,用递归来做,思路我是有的,就是依次尝试各个棋子,使之不与已经摆好的棋子冲突,只不过是否冲突的判断条件我想错了,即A与B不冲突,B与C不冲突,不代表A与C不冲突,我只考虑了相邻两个棋子的情况,而实际上应该从头开始遍历,这里有点像dp中的最长公共子序列的问题,不能仅考虑相邻的情况。

#include 

int hang[8],ans[92][8],num;
void queen(int n);

int main()
{
    queen(0);
    int b,n;
    scanf("%d",&n);
    while(n--){
        scanf("%d",&b);
        for(int i=0;i<8;i++){
            printf("%d",ans[b-1][i]);
        }
        printf("\n");

    }

}

void queen(int n)
{
    int i,j;
    if(n==8){
        for(i=0;i<8;i++){
            ans[num][i]=hang[i]+1;
        }
        num++;
        return;
    }

    for(i=0;i<8;i++){			//核心
        for(j=0;j

也没有必要转换成字符串的格式再输出,拿整型数组存储就可以了,hang做缓存数组,尽量不要拿ans数组直接操作。
*****************************************
今天9.7,刚刚重新写了一遍八皇后的算法,终于感觉搞懂了一点递归。。真的是调试出成果啊,不亲自调试一下什么也发现不了。重写的这一遍,刚开始递归的核心部分也就是queen中的循环弄错了,必须时刻把握i,j的含义。然后我就一直奇怪一点,n==8之后hang对ans赋完值了,为什么不用把hang的数据清空呢?马上不是要进行下一种情况了吗?本次的数据不会对下一次产生影响吗?显然这时我还没有理解递归的本质。递归实际上就是用来代替循环的,并且是基于 回溯法的,这点我通过调试程序发现的。对于0~7的每一个数(每一行),都会执行queen的核心程序,以期望找到在之前的行填好的条件下,还能有多少可能的结果,回溯是不断试错的过程,这样不行,往回退一步可能就行了(这里所谓“行”就是指在现有条件下能够填满8行,不再回溯而是直接走到return),而这时以前几行的数据是不需要删除的!当所有解都被找到后,queen自然就会结束,不用担心出不去的问题。

*******************

坚持,而不是打鸡血~

你可能感兴趣的:(递归)