資源簡介
八數碼問題C++代碼
代碼片段和文件信息
#include
#include
#include
using?namespace?std;
typedef?struct?node
{
int?a[3][3];
int?value;???//value??表示f(n)=d(n)+w(n)
int?height;??//搜索到當前節點的高度
int?from;???//表示該節點是由何種移動所得,1左移,2右移,3上移,4下移
char?path[1000];?????//保存前面搜索路徑
friend?bool?operator?(const?node?&t1const?node?&t2)
{
return?t1.value>t2.value;???//最小值優先
}
}node*nodelist;
class?eightnum
{
public:
eightnum()
{
int?ij;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
cin>>a[i][j];
if(a[i][j]==0)????//空格處置為9,便于后面比較求value
a[i][j]=9;
}
}
flag=0;
height=0;
}
bool?eightcan()????//判斷八數碼問題可否有解
{
/*
判斷給出的排列是否能夠通過有限次移動,達到目標狀態。
算法支持:
首先指定Less(k)k表示在九宮格中的某個數字k的取值范圍是1~9Less(k)
表示為k所在九宮格位置之后比k小的數字的個數。k=0時,自動轉換成k=9。
在下列排列中
1?0?3
7?2?4
6?8?5
Less(1)=0Less(9)=7Less(3)=1Less(7)=4Less(2)=0Less(4)=0
Less(6)=1Less(8)=0Less(5)=0
設定ij表示空格位置在九宮格中的位置,此例中i=1j=2。
判斷排列是否可在有限次移動得到解的條件是
k=1:9;
(sum(Less(k))+i+j)%2==0
*/
int?b[9];????????????????????//將二維數組轉化成一維數組便于操作
int?ijkxy;???????????????//ijk為控制變量,xy表示空格位置的橫坐標與縱坐標
//二維數組轉一維數組
k=0;
for(i=0;i<3;i++)??????????????
{
for(j=0;j<3;j++)
{
b[k]=a[i][j];
if(a[i][j]==9)
{
x=i+1;
y=j+1;
}
k++;
}
}
//求k=1:9;sum(Less(k))+i+j
int?sum=x+y;??????????????????
for(i=0;i<9;i++)
{
for(j=i;j<9;j++)
{
if(b[j] sum++;
}
}
if(sum%2==0)
return?true;
else
return?false;
}
int?f(node?now_node)????
{
/*求解該節點的f(n)=d(n)+w(n),在構造時已經將d(n)求出,
為n.height且n.value<<=n.heightw(n)表示該節點與目標狀態節點
不同的個數*/
int?ij;
int?value=0;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
if(now_node.a[i][j]!=i*3+j+1)
{
value++;
}
}
return?value+now_node.value;
}
int?solution()
{
if(!eightcan())????????????//判斷該排列是否能夠達到目標狀態
{
cout<<“該種排列無法移動得到目標狀態“< return?0;
}
int?ijxy;
priority_queue?q;?????//構造優先權隊列,以value值最小的優先出隊
node?p_first;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
p_first.a[i][j]=a[i][j];
}
p_first.value=0;
p_first.height=0;
p_first.from=0;
p_first.path[0]=48;
p_first.path[1]=0;
p_first.value=f(p_first);
if(resultOK(p_first)==1)?????//如果初始狀態即為目標狀態直接輸出
{
height=p_first.height;
path[0]=p_first.path[0];
path[1]=p_first.path[1];
return?1;
}
q.push(p_first);
while(q.empty()==false)
{
//獲得當前擴展節點的空格位置
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
if(q.top().a[i][j]==9)
{
x=i;y=j;
}
}
//進行移動操作
if(y-1>=0?&&?q.top().from!=2)
q.push(*moveleft(q.top()xy));
if(flag==1)
break;
if(y+1<=2?&&?q.top().from!=1)
q.push(*moveright(q.top()xy));
if(flag==1)
break;
if(x-1>=0?&&?q.top().from!=4)
q.push(*moveup(q.top()xy));
if(flag==1)
break;
if(x+1<=2?&&?q.top().from!=3)
- 上一篇:基于MFC的軟鍵盤
- 下一篇:vs使用mfc實現全屏截屏和自定義區域截屏修改
評論
共有 條評論