先是這周是搜索的題,網(wǎng)站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041
主要內(nèi)容是BFS,A*,IDA*,還有一道K短路的,.....木做,本來1009是說要用迭代加深做,但是我在他講之前就用BFSA了,雖然很耗時,但還是過了,10000MS的時限,我8000+MS.......
1001 Eight ?八數(shù)碼問題
先把代碼放上來
題目網(wǎng)址:?http://acm.hdu.edu.cn/showproblem.php?pid=1043
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<queue>
6 using namespace std;
7 class Node
8 {
9 public:
10 int maze[
3][
3];
//八數(shù)碼具體情況
11 int h,g;
//兩個估價函數(shù)
12 int x,y;
//空位的位置
13 int Hash;
//HASH值
14 bool operator<(
const Node n1)
const{
//優(yōu)先隊列第一關(guān)鍵字為h,第二關(guān)鍵字為g
15 return h!=n1.h?h>n1.h:g>
n1.g;
16 }
17 bool check()
//判斷是否合法
18 {
19 if(x>=
0&&x<
3&&y>=
0&&y<
3)
20 return true;
21 return false;
22 }
23 }s,u,v;
24 int HASH[
9]={
1,
1,
2,
6,
24,
120,
720,
5040,
40320};
//HASH的權(quán)值
25 int des=
322560;
//目標(biāo)情況的HASH值
26 int vis[
400000];
//判斷狀態(tài)已遍歷,初始為-1,否則為到達這步的轉(zhuǎn)向
27 int pre[
400000];
//路徑父節(jié)點
28 int way[
4][
2]={{
0,
1},{
0,-
1},{
1,
0},{-
1,
0}};
//四個方向
29 int get_hash(Node tmp)
//獲得HASH值
30 {
31 int a[
9],k=
0;
32 for(
int i=
0;i<
3;i++
)
33 for(
int j=
0;j<
3;j++
)
34 a[k++]=
tmp.maze[i][j];
35 int res=
0;
36 for(
int i=
0;i<
9;i++
){
37 int k=
0;
38 for(
int j=
0;j<i;j++
)
39 if(a[j]>
a[i])
40 k++
;
41 res+=HASH[i]*
k;
42 }
43 return res;
44 }
45 bool isok(Node tmp){
//求出逆序?qū)?#xff0c;判斷是否有解
46 int a[
9],k=
0;
47 for(
int i=
0;i<
3;i++
)
48 for(
int j=
0;j<
3;j++
)
49 a[k++]=
tmp.maze[i][j];
50 int sum=
0;
51 for(
int i=
0;i<
9;i++
)
52 for(
int j=i+
1;j<
9;j++
)
53 if(a[j]&&a[i]&&a[i]>
a[j])
54 sum++
;
55 return !(sum&
1);
//由于目標(biāo)解為偶數(shù),所以狀態(tài)的逆序數(shù)為偶數(shù)才可行
56 }
57 int get_h(Node tmp){
//獲得估價函數(shù)H
58 int ans=
0;
59 for(
int i=
0;i<
3;i++
)
60 for(
int j=
0;j<
3;j++
)
61 if(tmp.maze[i][j])
62 ans+=abs(i-(tmp.maze[i][j]-
1)/
3)+abs(j-(tmp.maze[i][j]-
1)%
3);
63 return ans;
64 }
65 void astar(){
//搜索
66 priority_queue<Node>que;
//優(yōu)先隊列
67 que.push(s);
68 while(!
que.empty())
69 {
70 u=
que.top();
71 que.pop();
//出隊
72 for(
int i=
0;i<
4;i++
)
73 {
74 v=
u;
75 v.x+=way[i][
0];
76 v.y+=way[i][
1];
77 if(v.check())
78 {
79 swap(v.maze[v.x][v.y],v.maze[u.x][u.y]);
//將空位和相鄰位交換
80 v.Hash=get_hash(v);
//得到HASH值
81 if(vis[v.Hash]==-
1)
//判斷是否已遍歷且是否可行
82 {
83 vis[v.Hash]=i;
//保存方向
84 v.g++;;
//代價++
85 pre[v.Hash]=u.Hash;
//保存v的父節(jié)點u
86 v.h=get_h(v);
//得到新的估價函數(shù)H
87 que.push(v);
//入隊
88 }
89 if(v.Hash==
des)
90 return ;
91 }
92 }
93 }
94 }
95 void print()
96 {
97 string ans;
98 char wu[
4]={
'r',
'l',
'd',
'u'};
99 ans.clear();
100 int nxt=
des;
101 while(pre[nxt]!=-
1)
//從終點往起點找路徑
102 {
103 ans+=
wu[vis[nxt]];
104 nxt=pre[nxt];
//上一個父節(jié)點
105 }
106 for(
int i=ans.size()-
1;i>=
0;i--
)
107 printf(
"%c",ans[i]);
108 printf(
"\n");
109 }
110 int main()
111 {
112 char str[
100];
113 while(gets(str)!=
NULL)
114 {
115 int k=
0;
116 memset(vis,-
1,
sizeof(vis));
117 memset(pre,-
1,
sizeof(pre));
118 for(
int i=
0;i<
3;i++
)
119 for(
int j=
0;j<
3;j++
)
120 {
121 if((str[k]<=
'9'&&str[k]>=
'0')||str[k]==
'x')
122 {
123 if(str[k]==
'x')
124 {
125 s.maze[i][j]=
0;
126 s.x=
i;
127 s.y=
j;
128 }
129 else
130 s.maze[i][j]=str[k]-
'0';
131 }
132 else
133 j--
;
134 k++
;
135 }
136 if(!isok(s))
//起始狀態(tài)不可行
137 {
138 printf(
"unsolvable\n");
139 continue;
140 }
141 s.Hash=
get_hash(s);
142 if(s.Hash==
des)
143 {
144 printf(
"\n");
145 continue;
146 }
147 vis[s.Hash]=-
2;
148 s.g=
0;s.h=
get_h(s);
149 astar(); //A*
150 print(); //打印路徑
151 }
152 return 0;
153 }
?
1 #include <iostream>
2 #include <stdio.h>
3 #include <
string.h>
4 #include <
string>
5 #include <algorithm>
6 #include <queue>
7 using namespace std;
8 class A
9 {
10 public:
11 int a[
3][
3];
12 int h,g;
13 int x,y;
14 int has;
15 bool operator<(
const A n)
const{
return h!=n.h?h>n.h:g>
n.g;}
16 bool check()
17 {
18 if (x>=
0&&x<=
2&&y>=
0&&y<=
2)
19 return true;
20 return false;
21 }
22 }s,w,r;
23 int H[
9]={
1,
1,
2,
6,
24,
120,
720,
5040,
40320};
24 int des=
322560;
25 int v[
400000];
26 int p[
400000];
27 int d[
4][
2]={{
0,
1},{
0,-
1},{
1,
0},{-
1,
0}};
28
29 bool ok(A c)
30 {
31 int q[
9],k=
0,i,j,sum=
0;
32 for(i=
0;i<
3;i++
)
33 for(j=
0;j<
3;j++
)
34 q[k++]=
c.a[i][j];
35 for(i=
0;i<
9;i++
)
36 for(j=i+
1;j<
9;j++
)
37 if(q[j]&&q[i]&&q[i]>
q[j])
38 sum++
;
39 return !(sum&
1);
40 }
41
42 int gethas(A c)
43 {
44 int q[
9],k=
0,i,j,sum=
0;
45 for(i=
0;i<
3;i++
)
46 for(j=
0;j<
3;j++
)
47 q[k++]=
c.a[i][j];
48 for(i=
0;i<
9;i++
)
49 {
50 int o=
0;
51 for(j=
0;j<i;j++
)
52 if(q[j]>
q[i])
53 o++
;
54 sum+=H[i]*
o;
55 }
56 return sum;
57 }
58
59 int geth(A c)
60 {
61 int sum=
0,i,j;
62 for(i=
0;i<
3;i++
)
63 for(j=
0;j<
3;j++
)
64 if(c.a[i][j])
65 sum+=abs(i-(c.a[i][j]-
1)/
3)+abs(j-(c.a[i][j]-
1)%
3);
66 return sum;
67 }
68
69 void astar()
70 {
71 int i;
72 priority_queue<A>
f;
73 f.push(s);
74 while(!
f.empty())
75 {
76 w=
f.top();
77 f.pop();
78 for(i=
0;i<
4;i++
)
79 {
80 r=
w;
81 r.x+=d[i][
0];
82 r.y+=d[i][
1];
83 if(r.check())
84 {
85 swap(r.a[w.x][w.y],r.a[r.x][r.y]);
86 r.has=
gethas(r);
87 if(v[r.has]==-
1)
88 {
89 v[r.has]=
i;
90 r.g++
;
91 p[r.has]=
w.has;
92 r.h=
geth(r);
93 f.push(r);
94 }
95 if(r.has==
des)
96 return ;
97 }
98 }
99 }
100 }
101
102 void print()
103 {
104 string str;
105 char wu[
4]={
'r',
'l',
'd',
'u'};
106 str.clear();
107 int next=
des,i;
108 while(p[next]!=-
1)
109 {
110 str+=
wu[v[next]];
111 next=
p[next];
112 }
113 for(i=str.size()-
1;i>=
0;i--
)
114 putchar(str[i]);
115 printf(
"\n");
116 }
117
118 int main()
119 {
120 char b[
100];
121 int i,j,k;
122 while(gets(b)!=
NULL)
123 {
124 memset(v,-
1,
sizeof(v));
125 memset(p,-
1,
sizeof(p));
126 k=
0;
127 for(i=
0;i<
3;i++
)
128 for(j=
0;j<
3;j++
)
129 {
130 if(b[k]==
'x')
131 {
132 s.a[i][j]=
0;
133 s.x=
i;
134 s.y=
j;
135 }
136 else if(b[k]>=
'0'&&b[k]<=
'9')
137 s.a[i][j]=b[k]-
'0';
138 else
139 j--
;
140 k++
;
141 }
142
143 if(!
ok(s))
144 {
145 printf(
"unsolvable\n");
146 continue;
147 }
148 s.has=
gethas(s);
149 if(s.has==
des)
150 {
151 printf(
"\n");
152 continue;
153 }
154 v[s.has]=-
2;
155 s.g=
0;
156 s.h=
geth(s);
157 astar();
158 print();
159 }
160 }
View Code ??
?
?
?1006 ? ?The Rotation Game ?
第二題 ?IDA*算法,感覺比上面那個簡單
題目網(wǎng)址:http://acm.hdu.edu.cn/showproblem.php?pid=1667
1 #include <stdio.h>
2 #include <iostream>
3 #include <
string.h>
4 #include <algorithm>
5 using namespace std;
6 int maxx(
int x,
int y,
int z) {
return max(max(x,y),z);}
//三個數(shù)的最大值
7 int a[
9][
8]=
{
8 0,
0,
0,
0,
0,
0,
0,
0,
9 0,
1,
3,
7,
12,
16,
21,
23,
10 0,
2,
4,
9,
13,
18,
22,
24,
11 0,
11,
10,
9,
8,
7,
6,
5,
12 0,
20,
19,
18,
17,
16,
15,
14,
13 0,
24,
22,
18,
13,
9,
4,
2,
14 0,
23,
21,
16,
12,
7,
3,
1,
15 0,
14,
15,
16,
17,
18,
19,
20,
16 0,
5,
6,
7,
8,
9,
10,
11
17 };
//每一縱行和橫行的編號
18 int re[
9]={
0,
6,
5,
8,
7,
2,
1,
4,
3};
//往回移對應(yīng)的編號
19 int mid[
9]={
0,
7,
8,
9,
12,
13,
16,
17,
18};
//中間的8個數(shù)的編號
20 char lu[]=
"OABCDEFGH";
//路徑
21 int b[
28];
//現(xiàn)狀
22 char father[
300];
//記錄父節(jié)點的編號
23 int dep;
//允許的深度
24
25 int geth(
int b[
28])
//獲得H值
26 {
27 int i,w[
4];
28 memset(w,
0,
sizeof(w));
29 for(i=
1;i<=
8;i++
)
30 w[b[mid[i]]]++
;
31 return 8-maxx(w[
1],w[
2],w[
3]);
32 }
33
34 int IDA(
int g)
35 {
36 int i,H,t,j;
37 if(g>=
dep)
38 return 0;
39 for(i=
1;i<=
8;i++
)
40 {
41 t=b[a[i][
1]];
42 for(j=
1;j<=
6;j++
)
43 b[a[i][j]]=b[a[i][j+
1]];
44 b[a[i][
7]]=
t;
45 father[g]=i;
//記錄父節(jié)點
46 H=geth(b);
//獲得最新的H
47 if(!
H)
48 return 1;
49 if(g+H<dep && IDA(g+
1))
//A*剪枝
50 return 1;
51 t=b[a[re[i]][
1]];
//回到上一步
52 for(j=
1;j<=
6;j++
)
53 b[a[re[i]][j]]=b[a[re[i]][j+
1]];
54 b[a[re[i]][
7]]=
t;
55 }
56 return 0;
57 }
58
59 int main()
60 {
61 int i;
62 while(~scanf(
"%d",&b[
1])&&b[
1])
63 {
64 for(i=
2;i<=
24;i++
)
65 scanf(
"%d",&
b[i]);
66 dep=
geth(b);
67 if(!dep)
//不需要移動
68 {
69 printf(
"No moves needed\n");
70 printf(
"%d\n",b[
8]);
71 continue;
72 }
73 while(!IDA(
0))
74 dep++
;
75 for(i=
0;i<=dep-
1;i++
)
76 printf(
"%c",lu[father[i]]);
77 printf(
"\n%d\n",b[
8]);
78 }
79 return 0;
80 }
?
轉(zhuǎn)載于:https://www.cnblogs.com/riddle/p/3407445.html
總結(jié)
以上是生活随笔為你收集整理的HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。