I Q 问题

西门子200的一个指令说是操作数为:I、Q、M、SM、T、C、V、S和L.这后面的这些字母代表什么意思啊,本人初
书上有吧.I是输入变量,Q是输出变量,其它你再看看,T是定时,C是计数,书看完了就知道啦!
为您推荐:
其他类似问题
扫描下载二维码什么是I/Q信号
什么是I/Q信号
当前的数字射频芯片,无一例外的用到了I/Q信号,就算是RFID芯片,内部也用到了I/Q信号,然而绝大部分射频人员,对于IQ的了解除了名字之外,基本上一无所知。
网上有大量关于IQ信号的资料,但都是公式一大堆,什么四相图,八相图之类的,最后还是不明白,除了知道这两个名次解释:
I:in-phase 表示同相
Q:quadrature 表示正交,与I相位差90度。
现在来解释I Q信号的来源:
最早通讯是模拟通讯,假设载波为cos(a),信号为cos(b),那么通过相成频谱搬移,就得到了
cos(a) * cos(b) = 1/2[cos( a + b) - cos(a - b) ]
这样在a载波下产生了两个信号,a+b和a-b,而对于传输来说,其实只需要一个信号即可,也就是说两者选择一个即可,另外一个没用,需要滤掉。但实际上滤波器是不理想的,很难完全滤掉另外一个,所以因为另外一个频带的存在,浪费了很多频带资源。
进入数字时代后,在某一个时刻传输的只有一个信号频率,比如0,假设为900MHz,1假设为901MHz,一直这两个频率在变化而已,并且不可能同时出现。这个不同于模拟通讯信号,比如电视机,信号的频带就是6.5MHz。还有一个严重的问题,就是信号频带资源越来越宝贵,不能再像模拟一样这么简单的载波与信号相乘,导致双边带信号。
大家最希望得到的,就是输入a信号和b信号,得到单一的a+b或者a-b即可。基于此目的,我们就把这个公式展开:
cos(a-b)=cos(a)cos(b)+sin(a)sin(b)
这个公式清楚的表明,只要把载波a和信号b相乘,之后他们各自都移相90度相乘,之后相加,就能得到a-b的信号了。这个在数字通讯,当前的半导体工艺完全可以做到:
1:数字通讯,单一时间只有一个频点,所以可以移相90度。
2:相加器、相乘器技术很容易实现。
如下图:手机GSM射频部分
接下来就很好办了,大家知道I就是cos(b),Q就是sin(b)
对这两个信号进行组合:
cos(b), sin(b)
cos(b), -sina(b)
-cos(b), sin(b)
-cos(b), -sin(b)
这个就是IQ信号的四相调制了。
之后为了编码更多的,就在这个里面折腾了,下面的就大家自己看书了。
注意,通过上面分析,大家知道IQ信号应该是正弦波模拟信号,手机上的频率是66KHz,大家在布线的时候一定要保证IQ信号不被干扰,毕竟是模拟信号,不然相乘相加之后就有很多杂波产生了,这个就是杂散了。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。IQ调制_百度百科
本词条缺少信息栏、名片图,补充相关内容使词条更完整,还能快速升级,赶紧来吧!
IQ调制IQ调制就是数据分为两路,分别进行载波调制,两路载波相互正交。I是in-phase(同相), q是 quadrature(正交)。
IQ调制简介
IQ调制就是数据分为两路,分别进行载波调制,两路载波相互正交。 I:in-phase(同相), q: quadrature(正交)[1]
IQ调制是矢量的方向问题,同相就是矢量方向相同的信号;正交分量就是两个信号矢量正交(差90°);IQ信号是一路是0°或180°,另一路是90°或270°,叫做I路和Q路,它们就是两路正交的信号[1]
IQ调制作用
因为I和Q是在相位上面正交的(不相干),可以作为两路信号看待。所以频谱利用率比单相调制提高一倍。但是IQ对解调要求高于单相(必须严格与I相差90度的整数倍,否则Q信号会混进I,I也会混进Q)[2]
简单的说就是数据分为两路,分别进行载波调制,两路载波相互正交。 正交信号就是两路频率相同,相位相差90度的载波,一般用sin和cos,与I,Q两路信号分别调制后一起发射,从而提高[3]
.百度知道.[引用日期]
.百度知道.[引用日期]
.百度知道.[引用日期]
企业信用信息八皇后问题_百度百科
八皇后问题
问题,是一个古老而著名的问题,是的典型案例。该问题是国际西洋棋棋手马克斯?贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
八皇后问题问题概述
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
八皇后问题最早是由国际西洋棋棋手马克斯?贝瑟尔于1848年提出。之后陆续有数学家对其进行研究,其中包括高斯和康托,并且将其推广为更一般的n皇后摆放问题。八皇后问题的第一个解是在1850年由弗朗兹?诺克给出的。诺克也是首先将问题推广到更一般的n皇后摆放问题的人之一。1874年,S.冈德尔提出了一个通过行列式来求解的方法,这个方法后来又被J.W.L.格莱舍加以改进。
艾兹格?迪杰斯特拉在1972年用这个问题为例来说明他所谓结构性编程的能力。
八皇后问题出现在1990年代初期的著名电子游戏第七访客中。
八皇后问题问题算法
八皇后问题C++
#include&iostream&
using&namespace&
static&int&gEightQueen[8]&=&{&0&},&gCount&=&0;
void&print()//输出每一种情况下棋盘中皇后的摆放情况
&&&&for&(int&i&=&0;&i&&&8;&i++)
&&&&&&&&int&
&&&&&&&&for&(inner&=&0;&inner&&&gEightQueen[i];&inner++)
&&&&&&&&&&&&cout&&&&"&";
&&&&&&&&for&(inner&=&gEightQueen[i]&+&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;
八皇后问题Pascal语言
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//主程序
&&&&for&m:=-7&to&16&do//数据初始化为0
&&&&&&&&b[m]:=0;//行数据初始化为0
&&&&&&&&c[m]:=0;//右上数据初始化为0
&&&&&&&&d[m]:=0;//右下数据初始化为0
&&&&ans:=0;
&&&&queen(1);//开始放置第一个皇后
&&&&writeln(ans);
八皇后问题Java 算法
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]=0;
for(int&i=1;i&=(2*8);i++)
rup[i]=lup[i]=0;&&//初始定义全部无皇后
queen=new&int[8+1];
public&void&backtrack(int&i){
showAnswer();
for(int&j=1;j&=8;j++){
if((column[j]==0)&&(rup[i+j]==0)&&(lup[i-j+8]==0)){
//若无皇后
queen[i]=j;
//设定为占用
column[j]=rup[i+j]=lup[i-j+8]=1;
backtrack(i+1);&&//循环调用
column[j]=rup[i+j]=lup[i-j+8]=0;
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);
八皇后问题Erlang算法
-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
#include&"stdio.h"
#define&N&8&//&N&表示皇后的个数&用来定义***的结构体
typedef&struct
int&&//&***的行号&&
int&&//&***的列号&
}ANSWER_TYPE;//&用来定义某个位置是否被占用&
typedef&enum
notoccued&=&0,&//&没被占用&&occued&=&1&//&被占用&
occued&=&1
}IFOCCUED;//&该列是否已经有其他皇后占用&
IFOCCUED&rowoccu[N];//&左上-右下对角位置已经有其他皇后占用&
IFOCCUED&LeftTop_RightDown[2&*&N&-&1];//&右上-左下对角位置已经有其他皇后占用
IFOCCUED&RightTop_LefttDown[2&*&N&-&1];//&最后的***记录&
ANSWER_TYPE&answer[N];
/*&寻找下一行占用的位置&*/
void&nextline(int&LineIndex)
static&int&asnnum&=&0;&/*&统计***的个数&*/
int&RowIndex&=&0;&/*&列索引&*/
int&PrintIndex&=&0;/*&按列开始遍历&*/
for&(RowIndex&=&0;&RowIndex&&&N;&RowIndex++)
/*&如果列和两个对角线上都没有被占用的话,则占用该位置&*/
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);
/*&如果已经到了最后一行,输出结果&*/
printf("\nThe&%dth&answer&is&:",&asnnum);
for&(PrintIndex&=&0;&PrintIndex&N;&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&main()
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 );}}
八皇后问题Qbasic版
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个对称位置,但是有些解经过对称操作后和没有操作前是一样的。
在一个标准的8×8的棋盘中,92个解当中有12个解是独立的。8×8棋盘的独立解如图所示。
如果把棋盘从8×8变成N×N, 八皇后问题就变成了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);
八皇后问题VB实现
主要利用思想 挨个判断是否可放置皇后若是 继续放置下一个 否则寻找其余位置
支持库 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 (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 );}}
企业信用信息

参考资料

 

随机推荐