什么时候可以心之所想挥手即成代码呢, 唉。。。。
凭什么人家可以的我不可以啊, 期待心之所想。。。。
一直都觉得回溯算法思想不难, 很好理解, 但是用c/c++表达出来总是似乎隔了层山也罢纱也罢, 有点距离, 于是又想到了8皇后
废话以后再说吧, 进入正题
此文除了描述下N皇后问题还会涉及到vs2005的一点疑问---谁可以解惑的可以留个言。
下图比较简陋, 不过是我的思想, 以四皇后为例, 初始矩阵值都是-1,皇后是一行一行放置的
如果某行某位置可以放置(若值等于-1则可以放置), 然后对下面的所有行进行填充处理(该皇后所在列和对角线位置都不能再放皇后了),之后就处理下一行, 如果下一行已经是最后一行, 那么就得到了一个解;
如果某行没有位置可以放置皇后了, 那么后退一行, 把刚刚放置的皇后清除, 同时清除由此皇后给下面若干行带来的影响, 同时考虑该皇后所在的下一个位置能不能放。
下面放代码吧
#include <stdio.h>
const int NUMBER = 10;
int mn[NUMBER][NUMBER];
int iCount = 0;
void clear()
{
for(int i = 0; i < NUMBER; i++)
{
for(int j = 0; j < NUMBER; j++)
{
mn[i][j] = -1;
}
}
}
void Fill(int i, int column)
{
int left = column;
int right = column;
int k = i+1;
for(k = i+1; k< NUMBER; k++)
{
if(mn[k][column] == -1)
{
mn[k][column] = i;
}
}
for(k = i+1; k < NUMBER; k++)
{
if(--left > -1)
{
if(mn[k][left] == -1)
mn[k][left] = i;
}
if(++right < NUMBER)
{
if(mn[k][right] == -1)
mn[k][right] = i;
}
}
}
void resetNextAllLine(int i)
{
for(int k = i+1; k < NUMBER; k++)
{
for(int co = 0; co < NUMBER; co++)
{
if(mn[k][co]>=i)
{
mn[k][co] = -1;
}
}
}
}
void myPrintf()
{
for(int i = 0; i < NUMBER; i++)
{
for(int j = 0; j < NUMBER; j++)
{
printf("%3d ", mn[i][j]);
}
printf("\n");
}
}
void NextLine(int i)
{
int col = 0;
for(col = 0; col < NUMBER; col++)
{
if(mn[i][col] == -1)
{
//ok
mn[i][col] = NUMBER;
//填充
Fill(i, col);
//printf("after Fill(%d,%d)\n", i, col);
//myPrintf();
//
if(i+1==NUMBER)
{
iCount++;
//printf("第%d个解:\n", iCount);
//myPrintf();
//如果只求一个解的话, 这里 return就可以了。
//回到上一行继续处理
mn[i][col] = NUMBER - 1;
//return;
}
else
{
NextLine(i+1);
return;
}
}
}
if(col == NUMBER)
{
i--;
//清除
resetNextAllLine(i);
//printf("after resetNextAllLine(%d)\n", i);
//myPrintf();
//回到上一行处理
if(i < 0)
{
printf("Total %d个解\nGame over\n", iCount);
return ;
}
else
{
//把上一行的一个赋值清除
for(int s = 0; s < NUMBER; s++)
{
if(mn[i][s] == NUMBER)
{
mn[i][s] = i;
}
}
//printf("after clear the one of previous line\n");
//myPrintf();
NextLine(i);
return;
}
}
}
void main()
{
clear();
NextLine(0);
}
上面有个常量NUMBER, 可以修改来打印出N皇后的值, 当然这不太灵活, 哈哈, 偷懒了, 数据简单啊
下面来陈述下问题所在:首先该代码是没有问题的, 在vs2005上创建的win32空工程, 然后加入该cpp文件, 选择release, OK, 你能得到下面的结果
皇后N | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
方案数据 | 2 | 10 | 4 | 40 | 92 | 352 | 724 |
但是但是, 如果你选择的不是release而是debug的话, 你会发现当NUMBER等于4,5,6,7,8时都是正确的, 当等于9的时候, 在第79个解的时候程序不再继续往下走了, 这是很神奇的事情, 我不懂。
谁懂的来解释下这个怪异的情况, 是哪里的东西没有清除掉还是??