广度优先算法必须先定义一个状态结构体,这个结构体包含如内容:
- 每走一步需要迭代更新的信息;
- 该状态对应的最短步数,一个状态的最短步数存在于它第一次被发现时。
广度优先算法需要用到的数据结构是队列,队列记录每个状态。广度优先算法利用队列先进先出的特性,由一个上一层状态不断扩展出新的下一层状态(上一层的状态比下一层的步数少1)。 在扩展状态的同时,算法每扩展一个新状态,都要探查它是否就是题设的最终状态。 核心代码如下:
state a;
a.x = s;a.y = 0;a.z = 0;a.bushu = 0;
mark[s][n][m] = 1;
q.push(a);
while(!q.empty()){
state now = q.front();q.pop();
int nows,nown,nowm;
state tmp;
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nows,s,nown,n);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
...
...
...
...
...
}
}
给出例题:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
int mark[100][100][100];
struct state
{
int x,y,z;
int bushu;
};
queue<state> q;
void AtoB(int &a,int va,int &b,int vb)
{
if(vb-b>=a){
b = b+a;
a = 0;
}else{
a = a-(vb-b);
b = vb;
}
}
int main()
{
int s,n,m;
while(cin>>s>>n>>m && s!=0 && n!=0 && m!=0){
int flag = 0;
int goodbushu = 0;
while(!q.empty()) q.pop();
state a;
a.x = s;a.y = 0;a.z = 0;a.bushu = 0;
mark[s][n][m] = 1;
q.push(a);
while(!q.empty()){
if(s%2!=0) break;
state now = q.front();q.pop();
int nows,nown,nowm;
state tmp;
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nows,s,nown,n);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
}
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nown,n,nows,s);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
}
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nows,s,nowm,m);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
}
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nowm,m,nows,s);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
}
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nown,n,nowm,m);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
}
nows = now.x;nown = now.y;nowm = now.z;
AtoB(nowm,m,nown,n);
if(mark[nows][nown][nowm]==false){
mark[nows][nown][nowm] = true;
tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
q.push(tmp);
if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
flag = 1;goodbushu = tmp.bushu;break;
}
}
}
if(flag!=1){
cout<<"NO"<<endl;
}else{
cout<<goodbushu<<endl;
}
}
}
|