皇后赛段水果皇后是什么水果意思

大家都在看
环舟山女子自行车赛进入第二赛段的争夺,该赛段被称为皇后赛段可见其重要性。
 大家都喜欢
 最受关注的热门栏目
视频集介绍
国家/地区:
视频简介:环岛赛2014第七赛段:同一个大冷门爆两次
点击:3250 次
日,“海南农信杯”2014第九届环海南岛国际公路自行车赛进行了“皇后赛段”――“海南农信社”东方-五指山赛段的争夺。来自法国马赛苹果车队的第四赛段冠军朱利安?安东玛奇(Julien Antomarchi)今天在一个决定性的双人突围中,力压阿斯塔纳车手安德烈?泽伊茨(Andrey Zeits)取得第二场单站胜利,并且在总成绩榜上以25秒的优势重返榜首。来自哈萨克斯坦的泽伊茨也凭借时间优势以及减秒登上总成绩榜次席,反超中国恒翔队车手王美银成为亚洲最佳蓝衫的获得者。身披黄衫出战的美利达-蓝波冲刺手尼科洛?博尼法齐奥(Niccolo Bonifazio)在第二集团中首位过线,取得赛段第三名,但是此战过后他已经落后朱利安多达35秒,彻底失去了争夺总冠军的机会。九架山、鹦哥岭和阿陀岭三大一级爬坡点的“联袂演出”,让今天的第七赛段比赛被认为是本届环岛赛的“皇后赛段”。由于3支UCI顶级职业队的存在,人们热切期待着激烈的总冠军争夺会在三个高难度爬坡上演。实际上,主车群没有这样的耐心,今天的比赛从一开始就呈现“六国大封相”的态势。在51.3公里处的第一个途中冲刺点到来之前,大集团里已经发生了多次群体性的进攻,使得上百人的参赛队伍被分裂成四五个小集团。我们甚至看到六名来自不同车队的车手一字排开争抢第一个冲刺点,场面非常壮观。混乱的局面直到第一个爬坡点即将到来时的90公里处才得到缓解,以圆点衫保有者塞吉?格雷卿(Sergiy Grechyn)为首的3名车手成功突围,并稳步拉开与主集团的时间差。尽管塞吉在昨天的访问中说到自己很可能在今天丢掉圆点衫,不过他的实际行动向人们证明了那只是他的谦虚。塞吉带领着两名突围同伴――贝尔金车队的托马斯?利泽(Thomas Leezer)以及波兰CCC车队的布兰尼斯劳?萨莫伊劳(Branislau Samoilau)通过了前两个爬坡点。这2个爬坡点头名带来的18个爬坡积分让他进一步巩固了爬坡王的地位。由于后面的比赛只剩下一个一级爬坡点和一个三级爬坡点,提供的爬坡积分最多也不会超过塞吉与爬坡榜第二名的分差,因此只要塞吉能平安完赛,就能稳获本届环岛赛的总爬坡王。在刷到两个爬坡点之后,3名兔子渐渐被人数锐减的主集团抓获,志在总冠军的车手们马上迎来阿陀岭一级爬坡点的决战。和鹦哥岭一样,阿陀岭下起了暴雨,湿滑的山路无论是上坡还是下坡都会给比赛增添额外的难度。美利达-蓝波车队、波兰CCC车队等爬坡能力强的车队都有数人在GC集团当中,蓝衫保有者王美银也跟上了该集团,然而主角并不是他们。距离阿陀岭坡顶还有5公里不到,来自阿斯塔纳车队的泽伊茨率先进攻,带出了前黄衫保有者朱利安。两人在到达阿陀岭山顶时领先美利达-蓝波车队引领的GC集团有1分钟的优势!最后的12公里下坡,突围两人的时间优势尽管逐步下降,但是他们还是出人意料地坚持到了最后。朱利安在最后的短坡冲刺中战胜积极领骑的泽伊茨,取得了这个决定性赛段的胜利!这场胜利带来的减秒以及大量的时间差使得这名“黑马”再次站上了总成绩领奖台。泽伊茨尽管输掉了赛段,但也收获一件亚洲最佳蓝衫。由尼科洛领衔的GC集团直到39秒之后才通过终点,损失的时间让他彻底失去争夺总冠军的希望,不过赛段第三名带来的冲刺积分让他继续稳获绿衫。“前面那次获胜并且夺过黄衫有些运气成分,今天3支顶级车队都在互相盯防,所以比赛很难。大雨让我们骑得很慢。我和泽伊茨在山顶还有1分多钟的时间优势,不过下了山就剩20多秒了。”朱利安说。由于后面2个赛段已经很难对总成绩有影响,所以朱利安也几乎确定获得本届环岛赛总冠军了。他和马赛苹果车队尚未续约,但相信这样的表现会打动车队管理层。与朱利安一起突围的泽伊茨接受采访时说,“我在最后十几公里决定进攻,朱利安跟上了我。我用尽力气想要甩掉他,但他很强。今天这个结果对我来说已经很满意了,因为我已经用尽了全力。亚洲最佳蓝衫和我们队服的颜色很接近,我很喜欢,我会试着保有它到比赛结束。”起点东方市是个大晴天,布尔格斯-BH车队的车手们一起去签到永远维诺车队不能永远唯唯诺诺,今天能否有超越老大哥阿斯塔纳的发挥呢?寿星公董晓勇给现场观众们送上小礼物,祝这位青海队名将生日快乐!美利达-蓝波车队在本届比赛成了众矢之的,他们能否夺得总冠军就看今天了热情的东方同学们上午10点,大部队正式向九年环岛历史上最具挑战性的赛段进发赛段早期,上届环岛赛的爬坡王塔西亚克就已经按耐不住要突围了,可惜今天要突围的人实在太多,他没能跑掉环岛赛老朋友迪米特里沉寂了几天之后今天终于发飙了,前面50公里他一直拉扯大集团主集团通过大桥,今天的比赛在进入爬坡之前已经异常残酷波兰CCC车队的队车似乎有个悲伤的故事原本躲在主集团后面等冲刺就行的冲刺手们今天要自力更生了;RTS-森地客车队的冲刺主将鲍里斯在今天退赛一字排开抢冲刺点的场面让人看醉又一次担起领骑重任的徐刚,今天他要抓的不是几个兔子,而是几个十多人的集团莫雷诺自从第四赛段过后就一直破罐子破摔爬坡点之前的第二冲刺点,马赛苹果车队已经无所不能了争夺冲刺点的领先集团慢慢退下,其中3个人突围了出来,其中圆点衫保有者塞吉收获颇丰,2个爬坡点的18个积分使他稳获总爬坡王赛事进入鹦哥岭之后就一直下雨,朱利安?安东玛奇保持在GC集团,似乎没人会料到他今天会复制黑马神话进入五指山爬坡,泽伊茨发动进攻带出了朱利安!这个举动可以说影响了整场环岛赛的冠军归属35秒后,GC集团才通过这个点;美利达-蓝波车队引领追击,不过他们的节奏比不上前面两个领先者完成任务的徐刚和BIKETO车友们打招呼“小黑”张伟凯坚持爬坡中扎卡洛夫瞄了我一眼,他在第三赛段有亮眼的突围表现同样完成任务的塞吉可以慢慢骑到终点了阿陀岭的下坡很考验技术,赵京彪把手变头甩歪了,左脚也破了位于五指山市区的终点被热情的观众围得水泄不通,朱利安?安东玛奇冲刺战胜泽伊茨,取得个人在本届比赛的第二胜!第二集团冲刺获胜也值得庆祝,尼科洛取得赛段第三;他身后的两名马赛苹果车手过线后,该队的车队总成绩也稳居第一,可谓双丰收王美银落后赛段冠军1分08秒通过终点,这个成绩已经是极其可贵了;此战过后王美银GC排第八,很有机会以前十名的成绩结束整场比赛赛段前三名开香槟;2011年之后,环岛赛之前未尝胜绩的朱利安很好的诠释了什么叫“三年不发市,发市当三年”绿衫对于尼科洛来说算不算安慰奖呢?和阿斯塔纳队服颜色很搭的蓝衫终究还是穿在了他们队身上,王美银前6个赛段的表现值得国人骄傲,期待有朝一日中国人能打败哈萨克斯坦军团塞吉?格雷卿披上圆点衫,这是他最完美的结束本赛季的方式了吧在第四赛段完成不可能任务的朱利安,今天再度创造了奇迹,三支顶级职业队的围追堵截,没能阻止他一战定江山!责任编辑:Jewels
职务:赛事记者
简介:一名初出茅庐的赛事记者,一名战斗力约等于五的公路车手,一名读得书少的井底蛙,一直为广东口音过重的普通话挣扎,不入流的专业水平备受业内外人士批判,从不放弃为下一次旅行的站票省吃俭用。未婚。
美骑网微信公众号
美骑易购微信公众号
BIKETO美骑网
您需要登录后才可以回复
快捷键回复:Ctrl + Enter
使用合作网站账号登录BIKETO八皇后问题_百度百科
关闭特色百科用户权威合作手机百科
收藏 查看&八皇后问题
八皇后一般指八皇后问题
问题,是一个古老而著名的问题,是的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 认为有76种方案。1854年在的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。发明后,有多种计算机语言可以解决此问题。外文名Eight queens时&&&&间1848年
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
八皇后问题最早是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出。之后陆续有数学家对其进行研究,其中包括高斯和康托,并且将其推广为更一般的n皇后摆放问题。八皇后问题的第一个解是在1850年由弗朗兹·诺克给出的。诺克也是首先将问题推广到更一般的n皇后摆放问题的人之一。1874年,S.冈德尔提出了一个通过行列式来求解的方法,这个方法后来又被J.W.L.格莱舍加以改进。
艾兹格·迪杰斯特拉在1972年用这个问题为例来说明他所谓结构性编程的能力。
八皇后问题出现在1990年代初期的著名电子游戏第七访客中。#include&iostream&
using&namespace&
static&int&gEightQueen[8]&=&{&0&},&gCount&=&0;
void&print()//输出每一种情况下棋盘中皇后的摆放情况
&&&&for&(int&outer&=&0;&outer&&&8;&outer++)
&&&&&&&&for&(int&inner&=&0;&inner&&&gEightQueen[outer];&inner++)
&&&&&&&&&&&&cout&&&&&&&;
&&&&&&&&for&(int&inner&=&gEightQueen[outer]&+&1;&inner&&&8;&inner++)
&&&&&&&&&&&&cout&&&&&&;
&&&&&&&&cout&&&&#&&&&&
&&&&cout&&&&&==========================\n&;
int&check_pos_valid(int&loop,&int&value)//检查是否存在有多个皇后在同一行/列/对角线的情况
&&&&for&(index&=&0;&index&&&&index++)
&&&&&&&&data&=&gEightQueen[index];
&&&&&&&&if&(value&==&data)
&&&&&&&&&&&&return&0;
&&&&&&&&if&((index&+&data)&==&(loop&+&value))
&&&&&&&&&&&&return&0;
&&&&&&&&if&((index&-&data)&==&(loop&-&value))
&&&&&&&&&&&&return&0;
&&&&return&1;
void&eight_queen(int&index)
&&&&for&(loop&=&0;&loop&&&8;&loop++)
&&&&&&&&if&(check_pos_valid(index,&loop))
&&&&&&&&&&&&gEightQueen[index]&=&
&&&&&&&&&&&&if&(7&==&index)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&gCount++,&print();
&&&&&&&&&&&&&&&&gEightQueen[index]&=&0;
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&&&&&eight_queen(index&+&1);
&&&&&&&&&&&&gEightQueen[index]&=&0;
int&main(int&argc,&char*argv[])
&&&&eight_queen(0);
&&&&cout&&&&&total=&&&&&gCount&&&&
&&&&return&0;
a:array[1..8]of&//记录皇后的行坐标
b,c,d:array[-7..16]of&//行,右上,右下斜线的占位标志
procedure&queen(j:longint);
&&&&if&j&8&then
&&&&&&&&inc(ans);//满足条件,找到一种方案
&&&&for&i:=1&to&8&do//每个皇后位置有八种可能
&&&&&&&&if(b[i]=0)and(c[i+j]=0)and(d[j-i]=0)then//如果位置没有被占则运行
&&&&&&&&begin
&&&&&&&&&&&&a[j]:=i;//皇后放置在此行
&&&&&&&&&&&&b[i]:=1;//占领第i行
&&&&&&&&&&&&c[i+j]:=1;//占领右上
&&&&&&&&&&&&d[j-i]:=1;//占领右下
&&&&&&&&&&&&queen(j+1);//递归
&&&&&&&&&&&&b[i]:=0;//回溯,恢复行占位标志
&&&&&&&&&&&&c[i+j]:=0;//回溯,恢复斜上方(右上)占位标志
&&&&&&&&&&&&d[j-i]:=0;///回溯,恢复斜下方(右下)占位标志
begin//主程序
&&&&form:=-7&to&16&do//数据初始化为0
&&&&&&&&b[m]:=0;//行数据初始化为0
&&&&&&&&c[m]:=0;//右上数据初始化为0
&&&&&&&&d[m]:=0;//右下数据初始化为0
&&&&ans:=0;
&&&&queen(1);//开始放置第一个皇后
&&&&writeln(ans);
public&class&Queen{
//同栏是否有皇后,1表示有
private&int[]&
//右上至左下是否有皇后
private&int[]&
//左上至右下是否有皇后
private&int[]&
private&int[]&
//解答编号
private&int&
public&Queen(){
column=new&int[8+1];
rup=new&int[(2*8)+1];
lup=new&int[(2*8)+1];
for(int&i=1;i&=8;i++)
column[i]=1;
for(int&i=1;i&=(2*8);i++)
rup[i]=lup[i]=1;
queen=new&int[8+1];
public&void&backtrack(int&i){
showAnswer();
for(int&j=1;j&=8;j++){
if((column[j]==1)&&(rup[i+j]==1)&&
(lup[i-j+8]==1)){
queen[i]=j;
//设定为占用
column[j]=rup[i+j]=lup[i-j+8]=0;
backtrack(i+1);
column[j]=rup[i+j]=lup[i-j+8]=1;
protected&void&showAnswer(){
System.out.println(&\n解答&+num);
for(int&y=1;y&=8;y++){
for(int&x=1;x&=8;x++){
if(queen[y]==x){
System.out.print(&Q&);
System.out.print(&.&);
System.out.println();
public&static&void&main(String[]args){
Queen&queen=new&Queen();
queen.backtrack(1);
-module(queen).-export([printf/0,&attack_range/2]).-define(MaxQueen,&4).%寻找字符串所有可能的排列%perms([])&-&%&[[]];%perms(L)&-&%&[[H&|&T]&||&H&&-&L,&T&&-&perms(L&--&[H])].perms([])&-&[[]];perms(L)&-&[[H&|&T]&||&H&&-&L,&T&&-&perms(L&--&[H]),&attack_range(H,T)&==&[]].printf()&-&L&=&lists:seq(1,&?MaxQueen),io:format(&~p~n&,&[?MaxQueen]),perms(L).%检测出第一行的数字攻击到之后各行哪些数字%left向下行的左侧检测%right向下行的右侧检测attack_range(Queen,&List)&-&attack_range(Queen,&left,&List)&++&attack_range(Queen,&right,&List).attack_range(_,&_,&[])&-&[];attack_range(Queen,&left,&[H&|&_])&when&Queen&-&1&=:=&H&-&[H];attack_range(Queen,&right,&[H&|&_])&when&Queen&+&1&=:=&H&-&[H];attack_range(Queen,&left,&[_&|&T])&-&attack_range(Queen&-&1,&left,&T);attack_range(Queen,&right,&[_&|&T])&-&attack_range(Queen&+&1,&right,&T).
对于八问题的实现,如果结合动态的图形演示,则可以使算法的描述更形象、更生动,使教学能产生良好的效果。下面是用Turbo C实现的八问题的图形程序,能够演示全部的92组解。八问题动态图形的实现,主要应解决以下两个问题。//eigqueprob.h
#define&N&8&//&N&表示皇后的个数&用来定义答案的结构体
typedef&struct
&&&&&&&&int&&//&答案的行号&&
&&&&&&&&int&&//&答案的列号&
ANSWER_TYPE;//&用来定义某个位置是否被占用&
typedef&enum
&&&&&&&&notoccued&=&0,&//&没被占用&&occued&=&1&//&被占用&
IFOCCUED;//&该列是否已经有其他皇后占用&
IFOCCUED&rowoccu[N];//&左上-右下对角位置已经有其他皇后占用&
IFOCCUED&LeftTop_RightDown[2*N-1];//&右上-左下对角位置已经有其他皇后占用
IFOCCUED&RightTop_LefttDown[2*N-1];//&最后的答案记录&
ANSWER_TYPE&answer[N];
#include&&eigqueprob.h&
/*&寻找下一行占用的位置&*/
void&nextline(int&LineIndex)
&&&&static&int&asnnum&=&0;&/*&统计答案的个数&*/&
&&&&int&RowIndex&=&0;&/*&列索引&*/&
&&&&int&PrintIndex&=&0;/*&按列开始遍历&*/&
&&&&for&(RowIndex=0;RowI
&&&&&&&&/*&如果列和两个对角线上都没有被占用的话,则占用该位置&*/&
&&&&&&&&if((notoccued&==&rowoccu[RowIndex])\&&&(notoccued&==&LeftTop_RightDown[LineIndex-RowIndex+N-1])\&&&(notoccued&==&RightTop_LefttDown[LineIndex+RowIndex]))&
&&&&&&&&{&
&&&&&&&&&&&&/*&标记已占用&*/&
&&&&&&&&&&&&rowoccu[RowIndex]&=&&
&&&&&&&&&&&&LeftTop_RightDown[LineIndex-RowIndex+N-1]&=&&
&&&&&&&&&&&&RightTop_LefttDown[LineIndex+RowIndex]&=&&
&&&&&&&&&&&&/*&标记被占用的行、列号&*/&
&&&&&&&&&&&&answer[LineIndex].line&=&LineI&answer[LineIndex].row&=&RowI
&&&&&&&&&&&&/*&如果不是最后一行,继续找下一行可以占用的位置&*/&
&&&&&&&&&&&&if&((N-1)&&&LineIndex&)&{&nextline(LineIndex+1);&
&&&&&&&&&&&&}
&&&&&&&&&&&&/*&如果已经到了最后一行,输出结果&*/&
&&&&&&&&&&&&else&
&&&&&&&&&&&&{&
&&&&&&&&&&&&&&&&asnnum++;&
&&&&&&&&&&&&&&&&printf(&\nThe&%dth&answer&is&:&,asnnum);
&&&&&&&&&&&&&&&&for&(PrintIndex=0;PrintIndex&
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&printf(&(%d,%d)&&,answer[PrintIndex].line+1,answer[PrintIndex].row+1);
&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&&&&&/*&每10个答案一组,与其他组隔两行&*/
&&&&&&&&&&&&&&&&if&((asnnum&%&10)&==&0)&
&&&&&&&&&&&&&&&&&&&&printf(&\n\n&);
&&&&&&&&&&&&}&
&&&&&&&&&&&&/*&清空占用标志,寻找下一组解&*/
&&&&&&&&&&&&rowoccu[RowIndex]&=&
&&&&&&&&&&&&LeftTop_RightDown[LineIndex-RowIndex+N-1]&=&&
&&&&&&&&&&&&RightTop_LefttDown[LineIndex+RowIndex]&=&
&&&&&&&&}&
&&&&int&i&=&0;&
&&&&/*&调用求解函数*/&
&&&&nextline(i);
&&&&/*&保持屏幕结果*/
&&&&getchar();
(a)为解决这个问题,我们把棋盘的横坐标定为i,纵坐标定为j,i和j的取值范围是从1到8。当某个占了位置(i,j)时,在这个位置的垂直方向、水平方向和斜线方向都不能再放其它皇后了。
用语句实现,可定义如下三个整型:a[8],b[15],c[24]。其中:
a[j-1]=1 第j列上无皇后
a[j-1]=0 第j列上有皇后
b[i+j-2]=1 (i,j)的对角线(左上至右下)无皇后
b[i+j-2]=0 (i,j)的对角线(左上至右下)有皇后
c[i-j+7]=1 (i,j)的对角线(右上至左下)无皇后
c[i-j+7]=0 (i,j)的对角线(右上至左下)有皇后
(b)为第i个皇后选择位置的算法如下:
for(j=1;j&=8;j++) /*第j个皇后在第j行*/
if ((i,j)位置为空)) /*即相应的三个数组的对应元素值为1*/
{占用位置(i,j) /*置相应的三个数组对应的元素值为0*/
为i+1个皇后选择合适的位置;
else 输出一个解
(2)图形存取
在Turbo C语言中,图形的存取可用如下实现:
size=(x1,y1,x2,y2) ;返回存储区域所需字节数。
arrow=malloc(size);建立指定大小的动态区域位图,并设定一指针arrow。
(x1,y1,x2,y2,arrow);将指定区域位图存于一。
putimage(x,y,arrow,copy)将位图置于屏幕上以(x,y)左上角的区域。
(3)程序清单如下
#include#include#include#includechar n[3]={'0','0'};/*用于记录第几组解*/int a[8],b[15],c[24],i;int h[8]={127,177,227,277,327,377,427,477};/*每个皇后的行坐标*/int l[8]={252,217,182,147,112,77,42,7}; /*每个皇后的列坐标*/void *void try(int i){for (j=1;j&=8;j++)if (a[j-1]+b[i+j-2]+c[i-j+7]==3) /*如果第i列第j行为空*/{ a[j-1]=0;b[i+j-2]=0;c[i-j+7]=0;/*占用第i列第j行*/ putimage(h[i-1],l[j-1],arrow,COPY_PUT); /*显示皇后图形*/ delay(500);/*延时*/ if(i&8) try(i+1); else /*输出一组解*/ { n[1]++; if (n[1]&'9') { n[0]++;n[1]='0'; } bar(260,300,390,340);/*显示第n组解*/ outtextxy(275,300,n); delay(3000); }a[j-1]=1; b[i+j-2]=1; c[i-j+7]=1; putimage(h[i-1],l[j-1],arrow,XOR_PUT); /*消去皇后,继续寻找下一组解*/ delay(500); }}int main(void){ int gdrive=DETECT,gmode, initgraph(&gdrive,&gmode,&&); errorcode=graphresult(); if (errorcode!=grOk) { printf(&Graphics error\n&);exit(1); } rectangle(50,5,100,40); rectangle(60,25,90,33);/* 画皇冠 */ line(60,28,90,28); line(60,25,55,15); line(55,15,68,25); line(68,25,68,10); line(68,10,75,25); line(75,25,82,10); line(82,10,82,25); line(82,25,95,15); line(95,15,90,25); size=imagesize(52,7,98,38); arrow=malloc(size); getimage(52,7,98,38,arrow); /* 把皇冠保存到缓冲区*/ clearviewport(); settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4); setusercharsize(3, 1, 1, 1); setfillstyle(1,4); for (i=0;i&=7;i++) a=1; for (i=0;i&=14;i++) b=1; for (i=0;i&=23;i++) c=1; for (i=0;i&=8;i++) line(125,i*35+5,525,i*35+5); /* 画棋盘 */ for (i=0;i&=8;i++) line(125+i*50,5,125+i*50,285); try(1); /* 调用递归函数 */ delay(3000); closegraph(); free(arrow);}#include&stdio.h&#include&memory.h&static int a[9][9],i,j,sum=0,t=1,column_status[9],slash_status[16],back_slash_status[17];int main(){ void print_board(); void go_up(); memset(column_status,0,sizeof(column_status)); memset(slash_status,0,sizeof(slash_status)); memset(back_slash_status,0,sizeof(back_slash_status)); memset(a,0,sizeof(a)); for(i=1;i&=8;i++) for(j=t;j&=8;j++) if(column_status[j]==0 && slash_status[i-j+8]==0 && back_slash_status[i+j]==0) { a[i][j]=1; column_status[j]=1; slash_status[i-j+8]=1; back_slash_status[i+j]=1; if (i==8) { print_board(); if(t==8) { go_up(); i--; } elsej=t; } else { t=1; } } else if(j==8) { if (i==1)return 0; else { go_up(); i--; } } return 0;}void print_board(){ printf(&第%d个方案为\n&,++sum); for(i=1;i&=8;i++) { for(j=1;j&=8;j++) { if (a[i][j]==1) { printf(&@ &); t=j; } else printf(&* &); } printf(&\n&); }}void go_up(){ i=i-1; for(j=1;j&=8;j++) { if(a[i][j]==1) { a[i][j]=0; column_status[j]=0; slash_status[i-j+8]=0; back_slash_status[i+j]=0; if (j==8) go_up(); else { t=j+1; } } }}易语言.支持库 iext3
.支持库 iext
.程序集 启动窗口程序集
.程序集变量皇后位置数组, 整数型, , &0&, 如:皇后位置数组[j]=4,表示第j列,第皇后位置数组[j]行有皇后
.程序集变量 行数组, 整数型, , &0&, 行数组[k]=1,表示第k行没有皇后
.程序集变量 右高左低数组, 整数型, , &0&, 右高左低数组[k]=1,表示第k条右高左低的斜线上没有皇后
.程序集变量 左高右低数组, 整数型, , &0&, 左高右低数组[k]=1,表示第k条左高右低的斜线上没有皇后
.程序集变量 棋盘行列值, 整数型, , , 棋盘规模变量
.子程序 __启动窗口_创建完毕
' 使用算法:
' 问题:N后问题
' 问题描述:
'中皇后可以攻击所在行,列,斜线上的每一个位置,按照此规则要在一个n*n的棋盘上放n个皇后使每一个皇后都不互相攻击
' 问题分析:
' (1) 引入1个数组模拟棋盘上皇后的位置
' 引入3个工作数组
' 行数组[k]=1,表示第k行没有皇后
' 右高左低数组[k]=1,表示第k条右高左低的斜线上没有皇后
' 左高右低数组[k]=1,表示第k条左高右低的斜线上没有皇后
' 观察棋盘找到规律
' 同一右高左低的斜线上的方格,它们的行号和列号之和相等;
' 同一左高右低的斜线上的方格,它们的行号和列号只差相等;
' 开始时,所有行和斜线上都没有皇后,从第一列的第一行配置第一个皇后开始,在第m列的皇后位置数组[m]行放置了一个合理的皇后之后,准备考察第m+1列时,在数组行数组[],右高左低数组[],左高右低数组[]中为第m列,皇后位置数组[m]的位置设定有皇后标志
' 如果按此放置位置得不到结果,则把当前列中的有皇后标记改为无皇后标记。
' 依次类推
' 当在棋盘最后一列上也找到合适的位置后得到结果。
' 通过上面规律可以推导出结果。
' 备注:
.子程序 __启动窗口_尺寸被改变
问题编辑框.宽度 = 高级选择夹1.宽度 - 16
问题编辑框.高度 = 高级选择夹1.高度 - 43
分析编辑框.宽度 = 问题编辑框.宽度
分析编辑框.高度 = 问题编辑框.高度
分组框1.宽度 = 高级选择夹1.宽度 - 18
分组框1.高度 = 高级选择夹1.高度 - 36
超级列表框1.宽度 = 分组框1.宽度 - 184
超级列表框1.高度 = 分组框1.高度 - 33
.子程序_计算图形按钮_被单击
.局部变量局部计次变量, 整数型, , , 在计次循环中记录循环次数
.局部变量局部计次变量2, 整数型
.局部变量 返回值, 整数型, , , 返回是否放置所有皇后成功
' 清空列表框
.计次循环首 (超级列表框1.取列数 (), )
超级列表框1.删除列 (0)
.计次循环尾 ()
.计次循环首 (超级列表框1.取表项数 (), )
超级列表框1.删除表项 (0)
.计次循环尾 ()
' 获得输入棋盘规模数据
棋盘行列值 = 到数值 (输入编辑框.内容)
.如果真 (棋盘行列值 & 1) ' 棋盘不能为0或负数
输入编辑框.内容 = “4”
.如果真结束
' 如果输入的棋盘规模过大提示是否等待
.如果真 (棋盘行列值 & 28)
.如果真 (信息框 (“您输入的数值过大,处理数据时程序将会有一段时间无响应,是否继续?”, #是否钮 + #询问图标, “请问:”) ≠ #是钮)
' 如果不想等待很长时间则返回
.如果真结束
.如果真结束
' 根据的到值定义棋盘行列,定义相关两斜行的值
重定义数组(行数组, 假, 棋盘行列值)
重定义数组(右高左低数组, 假, 2 × 棋盘行列值)
重定义数组(左高右低数组, 假, 2 × 棋盘行列值)
重定义数组(皇后位置数组, 假, 棋盘行列值)
' 行数组 [1]=1,表示第1行没有皇后
.计次循环首 (棋盘行列值, 局部计次变量)
行数组 [局部计次变量] = 1
.计次循环尾 ()
' 右高左低数组[1]=1,表示第1条右高左低的斜线上没有皇后
' 左高右低数组[1]=1,表示第1条左高右低的斜线上没有皇后
.计次循环首 (2 × 棋盘行列值, 局部计次变量)
右高左低数组 [局部计次变量] = 1
左高右低数组 [局部计次变量] = 1
.计次循环尾 ()
' 从第一列开始找出合适的放置方法
返回值 = 皇后问题子程序(1)
.判断开始 (返回值 = 1)
标签2.标题 = “找到结果” ' 得到结果显示在超级列表框中
超级列表框1.插入列 (, “0”, , , , )
超级列表框1.置列宽 (0, 30)
' 画棋盘列
.计次循环首 (棋盘行列值, 局部计次变量)
超级列表框1.插入列 (, 到文本 (局部计次变量), , , , )
超级列表框1.置列宽 (局部计次变量, 30)
.计次循环尾 ()
' 画棋盘行
.计次循环首 (棋盘行列值, 局部计次变量)
超级列表框1.插入表项 (, 到文本 (局部计次变量), , , , )
.计次循环尾 ()
' 显示排列结果
.计次循环首 (棋盘行列值, 局部计次变量)
.计次循环首 (棋盘行列值, 局部计次变量2)
' 如果当前行列坐标上有皇后
.判断开始 (皇后位置数组 [局部计次变量] = 局部计次变量2)
超级列表框1.置标题 (局部计次变量2 - 1, 局部计次变量, “皇”)
超级列表框1.置标题 (局部计次变量2 - 1, 局部计次变量, “*”)
.计次循环尾 ()
.计次循环尾 ()
标签2.标题 = “没有合适结果”
.皇后问题子程序, 整数型, , 在n*n棋盘的第k列上找合理的皇后放置位置
.参数 当前判断列, 整数型, , 当前在试探位置所在的列
.局部计次变量, 整数型, , , 试探合理位置时记录当前的行
.局部变量结果控制变量, 整数型, , , 找到结果变量为1,没有结果变量为0
局部计次变量= 1
结果控制变量 = 0
.判断循环首 (结果控制变量 = 0 且 局部计次变量 ≤ 棋盘行列值) ' 没有找到合理的解,并且还有没试过的行,继续循环
.如果真 (行数组 [局部计次变量] = 1 且 右高左低数组 [当前判断列 + 局部计次变量] = 1 且 左高右低数组 [棋盘行列值 + 当前判断列 - 局部计次变量] = 1) ' 是否在行,列,两斜线上都没有放置过皇后
皇后位置数组 [当前判断列] = 局部计次变量
'数组值等于 0,表示已经有皇后
行数组 [局部计次变量] = 0
右高左低数组 [当前判断列 + 局部计次变量] = 0
左高右低数组 [棋盘行列值 + 当前判断列 - 局部计次变量] = 0
.判断开始 (当前判断列 = 棋盘行列值)
返回 (1) ' 如果已经是最后一列,找到解,返回 1
结果控制变量 =皇后问题子程序 (当前判断列 + 1) ' 不是最后列,到下一列去放皇后,返回是否能放置皇后的信息
行数组 [局部计次变量] = 1
右高左低数组 [当前判断列 + 局部计次变量] = 1
左高右低数组 [棋盘行列值 + 当前判断列 - 局部计次变量] = 1
.如果真结束
局部计次变量= 局部计次变量 + 1
.判断循环尾 ()
返回 (结果控制变量) ' 返回最终是否有解的信息
循环实现* 数据表示
* 用一个 8 位的 8 进制数表示棋盘上皇后的位置:
* 比如: 表示:
* 第0列皇后在第4个位置
* 第1列皇后在第5个位置
* 第2列皇后在第6个位置
* 第7列皇后在第3个位置
* 循环变量从
(8进制数)的过程,就遍历了皇后所有的情况
* 程序中用八进制数用一个一维数组data[] 表示
* 检测冲突:
* 横列冲突:data == data[j]
* 斜列冲突:(data+i) == (data[j]+j) 或者 (data-i) == (data[j]-j)
* 采用循环,而不是递规,系统资源占有少
* 可计算 n皇后问题
* 把问题线性化处理,可以把问题分块,在分布式环境下用多台计算机一起算。
* 枚举部分还可以进行优化,多加些判断条件速度可以更快。
* 输出部分可以修改成棋盘形式的输出
*/public class Queen {int resultCpublic void compute ( int size ) {this.size =resultCount = 0;int data[] = new int[size]; // 所有可能的情况个数int i,j;// 计算所有可能的情况的个数count = 1;for ( i=0 ; i count = count *}// 对每一个可能的情况for ( i=0 ; i // 计算这种情况下的棋盘上皇后的摆放位置,用 8 进制数表示// 此处可优化int temp =for ( j=0 ; j data [j] = temp %temp = temp /}// 测试这种情况是否可行,如果可以,输出if ( test(data) )output( data );}}/** 测试这种情况皇后的排列是否可行**/public boolean test( int[] data ) {int i,j;for ( i=0 ; i for ( j=i+1 ; j // 测试是否在同一排if ( data == data[j] )// 测试是否在一斜线if ( (data+i) == (data[j]+j) )// 测试是否在一反斜线if ( (data-i) == (data[j]-j) )}}}/** 输出某种情况下皇后的坐标**/public void output ( int[] data ) {System.out.print ( ++resultCount + &: & );for ( i=0 ; i System.out.print ( &(& + i + &,& + data + &) & );}System.out.println ();}public static void main(String args[]) {(new Queen()).compute( 8 );}}10 I = 1
20 A(I) = 1
40 FOR K = I - 1 TO 1 STEP -1
50 IF A(I) = A(K) THEN 70
60 IF ABS(A(I) - A(K)) && I - K THEN 90
80 GOTO 100
100 IF I && 8 THEN 180
110 IF G = 0 THEN 180
120 FOR L = 1 TO 8
130 PRINT USING “##”; A(L);
140 NEXT L
150 PRINT “*”;
160 M = M + 1
170 IF M MOD 3 = 0 THEN PRINT
180 IF G = 0 THEN 230
190 IF I = 8 THEN 230
200 I = I + 1
210 A(I) = 1
220 GOTO 30
230 IF A(I) & 8 THEN 270
240 I = I - 1
250 IF I = 0 THEN 290
260 GOTO 230
270 A(I) = A(I) + 1
280 GOTO 30
300 PRINT “SUM=”; USING “##”; M;
//如果有一个Q 为 chess=j;
//则不安全的地方是 k行 j位置,j+k-i位置,j-k+i位置
class Queen8{
static final int QueenMax = 8;
static int oktimes = 0;
static int chess[] = new int[QueenMax];//每一个Queen的放置位置
public static void main(String args[]){
for (int i=0;i placequeen(0);
System.out.println(&\n\n\n八皇后共有&+oktimes+&个解法 made by yifi 2003&);
public static void placequeen(int num){ //num 为当前要放置的行数
boolean qsave[] = new boolean[QueenMax];
for(;i //下面先把安全位完成
i=0;//i 是要检查的数组值
while (i qsave[chess]=
int k=num-i;
if ( (chess+k &= 0) && (chess+k & QueenMax) ) qsave[chess+k]=
if ( (chess-k &= 0) && (chess-k & QueenMax) ) qsave[chess-k]=
//下面历遍安全位
for(i=0;i if (qsave==false)
if (num chess[num]=i;
placequeen(num+1);
else{ //num is last one
chess[num]=i;
oktimes++;
System.out.println(&这是第&+oktimes+&个解法 如下:&);
System.out.println(&第n行: 1 2 3 4 5 6 7 8&);
for (i=0;i String row=&第&+(i+1)+&行: &;
if (chess==0);
for(int j=0;j row+=&++&;
while(j System.out.println(row);
//历遍完成就停止
c#非递归实现
采用的思路大致是这样:
将一个向下移动一个位置;
如果没有成功移动(超出边界),失败;
如果成功移动,则判断当前位置是否可用?如果不可用,则重做 1;
继续给下一个安排位置。
如果第一个的所有位置都尝试完毕仍然没有可用的解决方案或者最后一个皇后已经安排完毕。
// AppEntry.csusing Snamespace Chenglin{ class AppEntry { static void Main(string[] args) { int queenNumber = 8; QueenRowCollection q = new QueenRowCollection(queenNumber); DateTime timeStarted = DateTime.N flag = q.PositionQueens(); TimeSpan ts = DateTime.Now.Subtract( timeStarted ); if( flag ) { Console.WriteLine( q.ToString() ); } else { Console.WriteLine( &Failed& ); } Console.WriteLine( & seconds has been elapsed.&, ts.TotalSeconds ); } }}// QueenRowCollection.csusing Susing System.Tnamespace Chenglin{ public class QueenRowCollection { public QueenRowCollection( int numberOfQueens ) { this.numberOfQueens = numberOfQ this.rows = new QueenRow[ numberOfQueens ]; } } public bool PositionQueens() { return PositionQueen( 0 ); } private bool PositionQueen( int row ) { if( row&=this.numberOfQueens ) { } QueenRow q = rows[row]; while(q.MoveNext()) { if( PositionAvailable( row, q.CurrentPosition ) ) { // An available position has been found for the current queen, // and try to find a proper position for the next queen. // // If no available position can be found for the next queen, // the current queen should move to the next position and try again. // if( PositionQueen( row+1 ) ) { // Both the current queen and the next queen // have found available positions. // } } } // No position is available for the current queen, // } private bool PositionAvailable( int row, int column ) { for( int i=row-1; i&=0; i-- ) { if( rows.PositionOccupied( column ) ) if( rows.PositionOccupied( column-(i-row) ) ) if( rows.PositionOccupied( column+(i-row) ) ) } } public override string ToString() { StringBuilder s = new StringBuilder(); foreach( QueenRow q in rows ) { s.AppendFormat( &&, q, Environment.NewLine ); } return s.ToString(); } private int numberOfQ private QueenRow [] }}
1// QueenRow.cs
3using System.T
5namespace Chenglin
7 public class QueenRow
9 public QueenRow( int numberOfPositions )
11 this.numberOfPositions = numberOfP
12 this.currentPosition = -1;
13 this.columns = new bool[ numberOfPositions ];
16 public bool MoveNext(){
17 if( currentPosition&=0 && currentPosition 18 columns[currentPosition] =
21 if( currentPosition 22 currentPosition ++;
23 columns[currentPosition] =
27 currentPosition = -1;
32 public bool PositionOccupied( int column ){
33 if( column&0 || column&=numberOfPositions ){
37 return columns[column];
40 public override string ToString()
42 StringBuilder s = new StringBuilder();
44 foreach( bool b in columns ){
45 s.AppendFormat( & &, (b ? &*& : &-&) );
48 return s.ToString();
51 public int CurrentPosition
53 get { return currentP }
56 private int currentP
57 private int numberOfP
58 private bool []
递归实现思路:
按列分别安排(Q),Q数目可随意指定(由于StackOverFlowException,只能到8)。
Q1可以放在任何位置;
然后尝试Q2,因为Q1的限制,Q2必须排除第二列与Q1行数插值大于2的位置;
依次尝试Qm... 如果Qm上没有剩余可用位置,则返回Qm-1,同时使Qm-1 放弃刚才使用位置;
当到达结尾Qn时,成功放置,则所有位置,作为一种解法;
当Q1尝试过首列所有位置后,算法结束。
结果统计并罗列所有解法。
堆栈修改:
“editbin /stack:4048000 D:\aa\ConsoleApplication2.exe”
using System.Collections.G
classMainClass
staticvoid Main()
int queens = int.Parse(Console.ReadLine());
List&Position& allPositions = GetAllPositions(queens);
int column = 0;
List&List&Position&& solutions = newList&List&Position&&();
EightQueens(queens, allPositions, column, newStack(), solutions);
for (int i = 0; i & solutions.C i++)
DisplayPositions(solutions[i]);
Console.WriteLine(solutions.Count);
Console.Read();
#region EightQueens
classStack
publicList&Position& CurrentPositions = newList&Position&();
List&KeyValuePair&int, List&Position&&& stack = newList&KeyValuePair&int, List&Position&&&();
publicvoid push(int i, List&Position& p )
stack.Add(newKeyValuePair&int, List&Position&&(i, p));
publicKeyValuePair&int, List&Position&& pop()
KeyValuePair&int, List&Position&& p = stack[stack.Count - 1];
stack.RemoveAt(stack.Count - 1);
publicvoid ClearFromKey(int key)
int idx = stack.FindIndex(a=&a.Key == key);
if (idx & -1)
stack.RemoveRange(idx, stack.Count - idx);
publicList&KeyValuePair&int, List&Position&&& StackList
returnthis.
classPosition
public Position(int left, int right)
this.left =
this.right =
publicint LeftDistence(Position p)
returnMath.Abs(this.left - p.left);
publicint RightDistence(Position p)
returnMath.Abs(this.right - p.right);
publicint QueenNumber = -1;
publicbool HasQueen
return QueenNumber != -1;
staticKeyValuePair&bool, int& EightQueens(int queens, List&Position& allPositions, int column, Stack stack, List&List&Position&& solutions)
if (column == queens)
List&Position& newLst = newList&Position&();
if(solutions.Count & 0)
for(int i = 0 ; i & solutions[solutions.Count - 1].Count -1 ; i++)
newLst.Add(solutions[solutions.Count - 1][i]);
solutions.Add(newLst);
return EightQueens(queens, allPositions, column -1, stack, solutions);
if (column == 0)
stack.ClearFromKey(1);
if (solutions.Count & 0 && solutions[solutions.Count - 1].Count != queens)
solutions.RemoveAt(solutions.Count - 1);
solutions.Add(newList&Position&());
List&Position&
if (solutions.Count & 0)
results = solutions[solutions.Count - 1];
results = newList&Position&();
List&Position& newPositions = newList&Position&();
if (stack.StackList.Exists(a =& a.Key == column))
newPositions = stack.StackList.Find(a =& a.Key == column).V
if (newPositions.Count & 0)
newPositions.RemoveAt(0);
newPositions = allPositions.FindAll(a =& a.left == column);
newPositions = FilterPositions(newPositions, results);
stack.push(column, newPositions);
if (newPositions.Count & 0)
newPositions[0].QueenNumber =
results.Add(newPositions[0]);
column = column + 1;
return EightQueens(queens, allPositions, column, stack, solutions);
stack.ClearFromKey(column);
if (stack.StackList.Count & 0 && stack.StackList.Find(a =& a.Key == 0).Value.Count & 0)
if (results.Count & 0)
results.RemoveAt(results.Count - 1);
return EightQueens(queens, allPositions, column - 1, stack, solutions);
if (solutions.Count & 0)
solutions.RemoveAt(solutions.Count - 1);
returnnewKeyValuePair&bool, int&(true, 0);
staticList&Position& GetAllPositions(int queens)
List&Position& positions = newList&Position&();
for (int i = 0; i & i++)
for (int j = 0; j & j++)
positions.Add(newPosition(i, j));
staticList&Position&FilterPositions(List&Position&original, Position newPosition)
return original.FindAll(a =& CheckPosition(a, newPosition));
staticList&Position& original, List&Position& newPositions)
if (newPositions == null || newPositions.Count == 0)
List&Position& ps = newList&Position&();
foreach(Position p in newPositions)
original.RemoveAll(a =& ! CheckPosition(a, p));
foreach (Position p in original)
ps.Add(p);
staticBoolean CheckPosition(Position newPosition, Position targetPosition)
int left = newPosition.LeftDistence(targetPosition);
int right = newPosition.RightDistence(targetPosition);
if (left & 1 || right & 1 || left == right)
staticvoid DisplayPositions(List&Position& positions)
for (int i = 0; i & positions.C i++)
Console.Write(positions[i].left);
Console.Write(positions[i].right + &,&);
Console.WriteLine();
#endregion
C++代码#includint width=8,lim=(1&void queen(int col,int ld,int rd) //分别是列,正斜线,反斜线,{ //col的二进制位中的1代表该行不能放的地方,ld,rd同理 if(col==lim){ans++;} //递归终止条件:col的二进制位在width(棋盘宽度)内都是1(放满了) int pos=lim&~(col|ld|rd); //col,ld,rd都是0的位可以放皇后,pos该位置1 while(pos) { int t=pos&- //取pos最右边的1位放皇后 pos-=t; queen(col|t,(ld|t)&&1,(rd|t)&&1); //往棋盘的下一行递归,左斜线的限制往左,右斜线往右,可以画图看看 }}int main(){ queen(0,0,0); // cout& return 0;}C++另外一种方法
#include &iostream&int a[8]; int b[8]; int c=0;bool flag(int pos){ for(i=0;i&++i) { if(a[i]==a[pos]) {} if(a[i]==a[pos]-(pos-i)||a[i]==a[pos+(pos-i)) {} }}void start(int pos){ for(i=0;i&n;++i) { a[pos]=i; if(flag(pos)) { if(pos==7) {c++;} else {start(pos+1);} } }}int main(){ int i,j; for(i=0;i&n;i++) a[i]=-1; start(0); cout&&c&&&种方法&; system(&pause&); return 0;}Python
#!/usr/bin/env python# 用一位数组模拟,数组中的值代表皇后所在的列,则皇后所有的位置# 的解空间是[0,1,2,3,4,5,6,7]的所有排列。对某一排列肯定满足不在# 同行同列的要求,只需要判断对任意两皇后不在斜对角线上就行# 即: |i - j| != |array[i] - array[j]|def check_diagonal(array): for i in range(len(array)): for j in range(i+1, len(array)): if j-i == abs(array[i] - array[j]): return False return Truedef permutation(array, begin_index): result = 0 if begin_index &= len(array)-1: if check_diagonal(array): #print array result += 1 else: for i in range(begin_index, len(array)): array[begin_index], array[i] = array[i], array[begin_index] result += permutation(array, begin_index+1) array[begin_index], array[i] = array[i], array[begin_index] return resultdef queen(num): array = range(num) return permutation(array, 0)if __name__ == '__main__': print queen(8)
思路:将皇后的位置用一个一维数组保存起来,类似栈,栈底从0开始
* @param $j 下一个皇后可能所在的位置
* @param $queen 存放之前符合所有条件的皇后的位置
* @return boolean 冲突时返回true
function isConflict($j,$queen)
for($i = 0,$len = count($queen); $i&$ $i++)
//与$queen中任意皇后在同一列或对角线上
if(in_array(abs($j-$queen[$i]),array(0,($len-$i))))
function backTracking(&$queen,&$j,$num)
$j = array_pop($queen);//将栈顶退出,下次循环就$j=$j+1,也就是从下个位置开始
if($j == $num-1)//若退出的是上一行的最后一列
if ($queen)//当栈不为空时,继续回退
$j = array_pop($queen);
else//栈已空,遍历结束
$j = $num -1;
* @param $num 皇后个数
function queens($num)
$queen = array();//存放一种结果
$queens = array();//存放所有结果
for($j=0;$j&$$j++)
if (isConflict($j,$queen))
if($j == $num-1)
backTracking($queen,$j,$num);
array_push($queen,$j);//没有任何冲突,入栈
$j = -1;//下次循环时, $j = 0
if(count($queen) == $num)//栈满了,已找到了符合所有条件的所有皇后,保存起来。
$queens[] = $
backTracking($queen,$j,$num);
var ans:array[1..8] //记录答案的,记录在第1到第8行所在的列;
lie:array[1..8] //记录1到8中某列是否已经被另一个占用;
zx:array[2..16] //正斜线(左下向右上),该斜线特点为:斜线上每一格的行加列的和一定,和为从2到16.。故可用2到16来表示这15条正斜线,于是该记录了2到16中某条正斜线是否已经被另一个占用;
fx:array[-7..7] //反斜线(左上向右下),该斜线特点为:斜线上每一格的行减列的差一定,差为从-7到7。故可用-7到7来表示这15条反斜线,于是该记录了2到16中某条正斜线是否已经被另一个占反;
temp: //记录总方案数;
//该子程序负责输出方案;
write('zuobiao');
for i:=1 to 8 do write(' (',i,',',ans[i],')'); //i代表行,ans[i]代表列;
procedure search(i:integer); //i为行,即表示放到了第几个(因为一行有且只有1个皇后);
var j:integer;
if i=9 then //递归出口,当搜索到第九行时,便得到一种方案;
//输出该方案;
inc(temp); //每输出(得到)一种方案,总方案数变加1;
for j:=1 to 8 do if not lie[j] and not zx[i+j] and not fx[i-j] then //当前位置,该列,正斜线,反斜线上均未被另一个占用,即可以摆放一个皇后;
lie[j]:= //设置标志,该行
zx[i+j]:= // 该正斜线
fx[i-j]:= // 该反斜线上已被占用,不可再放皇后;
ans[i]:=j; //记录答案(第i行所在列j);
search(i+1); //实行下一层递归;
lie[j]:= //恢复标志(回溯);
begin //主程序;
temp:=0; //给总方案数设初值为“0”;
fillchar(lie,sizeof(lie),0); //分别给列
fillchar(zx,sizeof(zx),0); // 正斜线
fillchar(fx,sizeof(fx),0); // 反斜线设初值为“假”
search(1); //从第一行开始进行搜索;
writeln(temp); //再输出总方案数;
#/bin/bash
canSet() { # 检查是否可放下的.
for ((n=0;n&y;n++)) ;do
((P[$n] == x)) && return 1 # 检查是否同一行, 如果是返回1 false
((P[$n] == x - n + y )) && return 1 #检查斜行.
((P[$n] == x + n - y )) && return 1 #检查另一方向斜行.
return 0 # 返回成功.
y=0 # y 是行,
for((i=0;i&8;i++)) ;do
P[$i]=-1 # p 是座位array , -1是不在棋盘上.
while (((y&8)&&(y&=0)));do #如果y&=8, 即找到结果, 如果y&0, 即找不到结果, 退出回卷
# echo ${P[*]}; # 打开这一注解,可看script 运行过程
f=0 # 设flag = 0, 用它检查否一整能不能放下
s=${P[$y]}+1 # 每一行放下的列位罝+1
for ((x=s;x&8;x++)); do #其他shell 用 for x in seq $s 7
if canSthen #如果可放下, 则
P[$y]=$x #记下位罝
((y++)) # 行位罝加1, 如用其他shell, 用 y=`expr $y + 1`代替
f=1 #设flag=1,即可效.
break #处理下一个
if [ $f -eq 0 ];then # 如果整行都不能放下.则
P[$y]=-1 #将由棋盘上拿下.
((y--)) #行位罝-1.
echo ${P[*]}; 打印数据在92个解中,很多解在棋盘上有对称关系,每一个棋子都有8个对称位置,如果一个解和另外一个解所有的棋子都呈同一种对称,那么这两个解之间就是对称关系。例如右边两个解实际上沿着垂直轴翻转,就是一个,因此不是独立的。相互间没有对称关系的解是独立解。虽然一个解可以有8个对称位置,但是有些解经过对称操作后和没有操作前是一样的。
在一个标准的8x8的棋盘中,92个解当中有12个解是独立的。8x8棋盘的独立解如图所示。
如果把棋盘从8X8变成NxN, 八问题就变成了N皇后问题。N从4以上都有解,并分别有相应的独立解。
下面是的数目于解数目的关系
数独立解全部解111
比较特殊的是,皇后6x6棋盘的解比5x5少,其余解的数目随着皇后数目增加。但似乎无数学可以描述。
pascal的解法是
x:array[1..1000]
function p1(k:longint):
for i:=1 to (k-1) do
if (x[i]=x[k]) or ((abs(x[i]-x[k]))=(abs(i-k))) then p1:=
procedure p2;
procedure p3(k:longint);
if (k=n+1) then
for i:=1 to n do
if p1(k) then p3(k+1);
readln(n);
end.主要利用思想 挨个判断是否可放置若是 继续放置下一个 否则寻找其余位置
支持库 iext3
.支持库 iext
.启动窗口程序集
.程序集变量位置, 整数型, , &0&, 如:皇后位置数组[j]=4,表示第j列,第皇后位置数组[j]行有皇后
.程序集变量 行数组, 整数型, , &0&, 行数组[k]=1,表示第k行没有皇后
.程序集变量 右高左低数组, 整数型, , &0&, 右高左低数组[k]=1,表示第k条右高左低的斜线上没有皇后
.程序集变量 左高右低数组, 整数型, , &0&, 左高右低数组[k]=1,表示第k条左高右低的斜线上没有皇后
.程序集变量 棋盘行列值, 整数型, , , 棋盘
.__启动窗口_创建完毕
' 使用算法:
' 问题:N后问题
' 问题描述:
'中皇后可以攻击所在行,列,斜线上的每一个位置,按照此规则要在一个n*n的棋盘上放n个皇后使每一个皇后都不互相攻击
' 问题分析:
' (1) 引入1个数组模拟棋盘上皇后的位置
' 引入3个工作数组
' 行数组[k]=1,表示第k行没有皇后
' 右高左低数组[k]=1,表示第k条右高左低的斜线上没有皇后
' 左高右低数组[k]=1,表示第k条左高右低的斜线上没有皇后
' 观察棋盘找到规律
' 同一右高左低的斜线上的方格,它们的行号和列号之和相等;
' 同一左高右低的斜线上的方格,它们的行号和列号只差相等;
' 开始时,所有行和斜线上都没有皇后,从第一列的第一行配置第一个皇后开始,在第m列的皇后位置数组[m]行放置了一个合理的皇后之后,准备考察第m+1列时,在数组行数组[],右高左低数组[],左高右低数组[]中为第m列,皇后位置数组[m]的位置设定有皇后标志
' 如果按此放置位置得不到结果,则把当前列中的有皇后标记改为无皇后标记。
' 依次类推
' 当在棋盘最后一列上也找到合适的位置后得到结果。
' 通过上面规律可以推导出结果。
' 备注:
.子程序 __启动窗口_尺寸被改变
问题编辑框.宽度 = 高级选择夹1.宽度 - 16
问题编辑框.高度 = 高级选择夹1.高度 - 43
分析编辑框.宽度 = 问题编辑框.宽度
分析编辑框.高度 = 问题编辑框.高度
分组框1.宽度 = 高级选择夹1.宽度 - 18
分组框1.高度 = 高级选择夹1.高度 - 36
超级1.宽度 = 分组框1.宽度 - 184
超级列表框1.高度 = 分组框1.高度 - 33
.子程序_计算图形按钮_被单击
.局部计次变量, 整数型, , , 在计次循环中记录循环次数
.局部变量局部计次变量2, 整数型
.局部变量, 整数型, , , 返回是否放置所有皇后成功
' 清空列表框
.计次循环首 (超级列表框1.取列数 (), )
超级列表框1.删除列 (0)
.计次循环尾 ()
.计次循环首 (超级列表框1.取表项数 (), )
超级列表框1.删除表项 (0)
.计次循环尾 ()
' 获得输入棋盘规模数据
棋盘行列值 = 到数值 (输入编辑框.内容)
.如果真 (棋盘行列值 & 1) ' 棋盘不能为0或负数
输入编辑框.内容 = “4”
.如果真结束
' 如果输入的棋盘规模过大提示是否等待
.如果真 (棋盘行列值 & 28)
.如果真 (信息框 (“您输入的数值过大,处理数据时程序将会有一段时间无响应,是否继续?”, #是否钮 + #询问图标, “请问:”) ≠ #是钮)
' 如果不想等待很长时间则返回
.如果真结束
.如果真结束
' 根据的到值定义棋盘行列,定义相关两斜行的值
重定义数组(行数组, 假, 棋盘行列值)
重定义数组(右高左低数组, 假, 2 × 棋盘行列值)
重定义数组(左高右低数组, 假, 2 × 棋盘行列值)
重定义数组(皇后位置数组, 假, 棋盘行列值)
' 行数组 [1]=1,表示第1行没有皇后
.计次循环首 (棋盘行列值, 局部计次变量)
行数组 [局部计次变量] = 1
.计次循环尾 ()
' 右高左低数组[1]=1,表示第1条右高左低的斜线上没有皇后
' 左高右低数组[1]=1,表示第1条左高右低的斜线上没有皇后
.计次循环首 (2 × 棋盘行列值, 局部计次变量)
右高左低数组 [局部计次变量] = 1
左高右低数组 [局部计次变量] = 1
.计次循环尾 ()
' 从第一列开始找出合适的放置方法
返回值 = 皇后问题子程序(1)
.判断开始 (返回值 = 1)
标签2.标题 = “找到结果” ' 得到结果显示在超级列表框中
超级列表框1.插入列 (, “0”, , , , )
超级列表框1.置列宽 (0, 30)
' 画棋盘列
.计次循环首 (棋盘行列值, 局部计次变量)
超级列表框1.插入列 (, 到文本 (局部计次变量), , , , )
超级列表框1.置列宽 (局部计次变量, 30)
.计次循环尾 ()
' 画棋盘行
.计次循环首 (棋盘行列值, 局部计次变量)
超级列表框1.插入表项 (, 到文本 (局部计次变量), , , , )
.计次循环尾 ()
' 显示排列结果
.计次循环首 (棋盘行列值, 局部计次变量)
.计次循环首 (棋盘行列值, 局部计次变量2)
' 如果当前行列坐标上有皇后
.判断开始 (皇后位置数组 [局部计次变量] = 局部计次变量2)
超级列表框1.置标题 (局部计次变量2 - 1, 局部计次变量, “皇”)
超级列表框1.置标题 (局部计次变量2 - 1, 局部计次变量, “*”)
.计次循环尾 ()
.计次循环尾 ()
标签2.标题 = “没有合适结果”
.子程序皇后问题子程序, 整数型, , 在n*n棋盘的第k列上找合理的皇后放置位置
.参数 当前判断列, 整数型, , 当前在试探位置所在的列
.局部变量局部计次变量, 整数型, , , 试探合理位置时记录当前的行
.局部变量结果, 整数型, , , 找到结果变量为1,没有结果变量为0
局部计次变量= 1
结果控制变量 = 0
.判断循环首 (结果控制变量 = 0 且 局部计次变量 ≤ 棋盘行列值) ' 没有找到合理的解,并且还有没试过的行,继续循环
.如果真 (行数组 [局部计次变量] = 1 且 右高左低数组 [当前判断列 + 局部计次变量] = 1 且 左高右低数组 [棋盘行列值 + 当前判断列 - 局部计次变量] = 1) ' 是否在行,列,两斜线上都没有放置过皇后
皇后位置数组 [当前判断列] = 局部计次变量
'数组值等于 0,表示已经有皇后
行数组 [局部计次变量] = 0
右高左低数组 [当前判断列 + 局部计次变量] = 0
左高右低数组 [棋盘行列值 + 当前判断列 - 局部计次变量] = 0
.判断开始 (当前判断列 = 棋盘行列值)
返回 (1) ' 如果已经是最后一列,找到解,返回 1
结果控制变量 =皇后问题子程序 (当前判断列 + 1) ' 不是最后列,到下一列去放皇后,返回是否能放置皇后的信息
行数组 [局部计次变量] = 1
右高左低数组 [当前判断列 + 局部计次变量] = 1
左高右低数组 [棋盘行列值 + 当前判断列 - 局部计次变量] = 1
.如果真结束
局部计次变量= 局部计次变量 + 1
.判断循环尾 ()
返回 (结果控制变量) ' 返回最终是否有解的信息
* 用一个 8 位的 8 进制数表示棋盘上皇后的位置:
* 比如: 表示:
* 第0列皇后在第4个位置
* 第1列皇后在第5个位置
* 第2列皇后在第6个位置
* 第7列皇后在第3个位置
* 循环变量从
(8进制数)的过程,就遍历了皇后所有的情况
* 程序中用用一个一维数组[] 表示
* 检测冲突:
* 横列冲突:data == data[j]
* 斜列冲突:(data+i) == (data[j]) 或者 (data-i) == (data[j]-j)
* 采用循环,而不是递规,系统资源占有少
* 可计算 n皇后问题
* 把问题线性化处理,可以把问题分块,在分布式环境下用多台计算机一起算。
* 枚举部分还可以进行优化,多加些判断条件速度可以更快。
* 输出部分可以修改成棋盘形式的输出
*/public class Queen {int resultCpublic void compute ( int size ) {this.size =resultCount = 0;int data[] = new int[size]; // 所有可能的情况个数int i,j;// 计算所有可能的情况的个数count = 1;for ( i=0 ; i count = count *}// 对每一个可能的情况for ( i=0 ; i // 计算这种情况下的棋盘上皇后的摆放位置,用 8 进制数表示// 此处可优化int=for ( j=0 ; j data [j] = temp %temp = temp /}// 测试这种情况是否可行,如果可以,输出if ((data) )output( data );}}/** 测试这种情况皇后的排列是否可行**/public boolean test( int[] data ) {int i,j;for ( i=0 ; i for ( j=i+1 ; j // 测试是否在同一排if ( data == data[j] )// 测试是否在一斜线if ( (data+i) == (data[j]+j) )// 测试是否在一反斜线if ( (data-i) == (data[j]-j) )}}}/** 输出某种情况下皇后的坐标**/public void output ( int[] data ) {System.out.print ( ++resultCount + &: & );for ( i=0 ; i System.out.print ( &(& + i + &,& + data + &) & );}System.out.println ();}public static void main(String args[]) {(new Queen()).compute( 8 );}}
新手上路我有疑问投诉建议参考资料 查看

我要回帖

更多关于 外盘内盘是什么意思 的文章

 

随机推荐