算法编程(JAVA)--八皇后问题

来源:互联网 发布:哪个淘宝u站返最多 编辑:程序博客网 时间:2024/05/22 01:52
题目:在一个8×8国际象棋盘上,有8个皇后,每个皇后占一格;
要求皇后间不会出现相互“攻击”的现象,即不能有两个皇后处在同一行、同一列或同一对角线上。

问共有多少种不同的方法?

解题思路:通过一个int[8][8]的二位数组构建棋盘,初始化为0,我们可以定义如果该位置摆放了皇后那么该位置对应的二维数组被置为-1。因为皇后之间不能相互攻击,所以我们要明确指出该皇后的影响范围,于是我们采用将该皇后能影响到的棋盘位置全部+1,比如:

-1111111111000000101000001001000010001000100001001000001010000001

这样我们就可以判断,只要是0的地方就可以放置皇后,只要是-1就是皇后的位置,只要是大于0的地方就是被皇后影响的地方。这样做有个什么好处呢,就是我们再回溯时只需要通过简单的对皇后的影响范围进行-1就可以取消她的影响范围了。下面直接贴出代码,后面有注释。如果读者有什么疑惑可以给我留言~~

<pre name="code" class="java">public class Main {static int[][] Arr = new int[8][8];static int Count=0;public static void main(String[] args){Cal(0,0);//递归函数,传入当前选中位置是第几行第几列System.out.println(Count);}public static void Cal(int a,int b){if(a==8){Count++;for(int j=0;j<8;j++){//寻找第8行已经摆放了的皇后的位置if(Arr[7][j]==-1){Sub(7,j);//找到后拿掉皇后,并且取消掉该皇后的影响return;}}}else{boolean Flag=true;//设置一个标志位,用来判断该行是否还有可以摆放皇后的位置for(int i=0;i<8;i++){if(Arr[a][i]==0){Flag=false;//若有可以摆放皇后的位置,将标志位置为falseAdd(a,i);//摆放这个皇后,并且添加该皇后的影响Cal(a+1,i);//将下一个状态带入状态方程}}if(Flag==true){//如果没有找到可以摆放皇后的位置,就取消掉上一层的皇后的位置,并且消除该皇后的影响Sub(a-1,b);return;}if(Flag==false&&a>0){//如果有改层有可以摆放皇后的位置,就要在回溯时拿掉该皇后,并且取消该皇后的影响for(int i=0;i<8;i++){if(Arr[a-1][i]==-1){Sub(a-1,i);return;}}}return;}}public static void Add(int x,int y){//添加皇后,并且添加该皇后的影响Arr[x][y]=-1;for(int i=0;i<8;i++){if(i!=y)Arr[x][i]=Arr[x][i]+1;}for(int i=0;i<8;i++){if(i!=x)Arr[i][y]=Arr[i][y]+1;}for(int i=-7;i<8;i++){//左上到右下if((i+x)>=0&&(i+x)<8&&i!=0&&(i+y)>=0&&(i+y)<8){Arr[x+i][y+i]=Arr[x+i][y+i]+1;}}for(int i=-7;i<8;i++){//左下到右上if((x-i)>=0&&(x-i)<8&&i!=0&&(i+y)>=0&&(i+y)<8){Arr[x-i][y+i]=Arr[x-i][y+i]+1;}}}public static void Sub(int x,int y){//消去该皇后的影响Arr[x][y]=0;for(int i=0;i<8;i++){if(i!=y)Arr[x][i]=Arr[x][i]-1;}for(int i=0;i<8;i++){if(i!=x)Arr[i][y]=Arr[i][y]-1;}for(int i=-7;i<8;i++){//左上到右下if((i+x)>=0&&(i+x)<8&&i!=0&&(i+y)>=0&&(i+y)<8){Arr[x+i][y+i]=Arr[x+i][y+i]-1;}}for(int i=-7;i<8;i++){//左下到右上if((x-i)>=0&&(x-i)<8&&i!=0&&(i+y)>=0&&(i+y)<8){Arr[x-i][y+i]=Arr[x-i][y+i]-1;}}}}


0 0
原创粉丝点击