对于常规的Dfs/Bfs就不说了,博弈搜索都是后话,这里主要整理高效率的搜索(也没高哪去)
搜索的时间复杂度一般是xn指数级别的所以在这里为了提高搜索效率,最好的方法是降指,以下的方法都是基于这种想法的。
1.双向Bfs、Dfs
适用于操作可逆的搜索,采用meet in the middle 的想法,将前一半搜出,后一半查询,或者直接两边一起搜,将时间复杂度降至2*xn/2
大概我是第一个用Dfs的人。
1 #include<map>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 struct cio{
6 int i,j;
7 void move(int direction);
8 bool Insert(void);
9 bool friend operator < (cio x,cio y)
10 {
11 if(x.i!=y.i)
12 return x.i<y.i;
13 return x.j<y.j;
14 }
15 bool friend operator == (cio x,cio y)
16 {
17 return (x.i==y.i)&&(x.j==y.j);
18 }
19 bool friend operator <=(cio x,cio y)
20 {
21 return (x<y)||(x==y);
22 }
23 bool friend operator >=(cio x,cio y)
24 {
25 return !(x<y);
26 }
27 bool friend operator !=(cio x,cio y)
28 {
29 return !(x==y);
30 }
31 bool friend operator >(cio x,cio y)
32 {
33 return !(x<=y);
34 }
35 };
36 struct sit{
37 cio c[5];
38 bool friend operator < (sit x,sit y)
39 {
40 for(int i=1;i<=4;i++)
41 if(x.c[i]!=y.c[i])
42 return x.c[i]<y.c[i];
43 return false;
44 }
45 bool friend operator == (sit x,sit y)
46 {
47 for(int i=1;i<=4;i++)
48 if(x.c[i]!=y.c[i])
49 return false;
50 return true;
51 }
52 bool friend operator <=(sit x,sit y)
53 {
54 return (x<y)||(x==y);
55 }
56 bool friend operator >=(sit x,sit y)
57 {
58 return !(x<y);
59 }
60 bool friend operator !=(sit x,sit y)
61 {
62 return !(x==y);
63 }
64 bool friend operator >(sit x,sit y)
65 {
66 return !(x<=y);
67 }
68 bool Insert(void);
69 void sort(void);
70 }sta,fin,anc;
71 int di[10]={0,0,0,1,-1};
72 int dj[10]={0,1,-1,0,0};
73 std::map<sit,int>Map;
74 bool ans_found;
75 bool cmp(cio x,cio y);
76 bool check_and_ban(cio one);
77 void Dfs_from_sta(int step,sit S);
78 void Dfs_from_end(int step,sit S);
79 sit Move(int which,int where,sit S);
80 int main()
81 {
82 while(scanf("%d",&sta.c[1].i)!=EOF)
83 {
84 scanf("%d",&sta.c[1].j);
85 for(int i=2;i<=4;i++)
86 scanf("%d%d",&sta.c[i].i,&sta.c[i].j);
87 for(int i=1;i<=4;i++)
88 scanf("%d%d",&fin.c[i].i,&fin.c[i].j);
89 Map.clear();
90 Map[anc]=998244353;
91 ans_found=false;
92 Dfs_from_sta(1,sta);
93 Dfs_from_end(1,fin);
94 if(ans_found)
95 puts("YES");
96 else
97 puts("NO");
98 }
99 return 0;
100 }
101 void Dfs_from_sta(int step,sit S)
102 {
103 S.sort();
104 if(S==anc)
105 return ;
106 Map[S]=20010728;
107 if(step==5)
108 return ;
109 step++;
110 for(int chess=1;chess<=4;chess++)
111 for(int direction=1;direction<=4;direction++)
112 Dfs_from_sta(step,Move(chess,direction,S));
113 return ;
114 }
115 void Dfs_from_end(int step,sit S)
116 {
117 if(ans_found)
118 return ;
119 S.sort();
120 if(Map.find(S)!=Map.end()&&S!=anc)
121 {
122 ans_found=true;
123 return ;
124 }
125 if(step==5)
126 return ;
127 step++;
128 for(int chess=1;chess<=4;chess++)
129 for(int direction=1;direction<=4;direction++)
130 Dfs_from_end(step,Move(chess,direction,S));
131 return ;
132 }
133 sit Move(int which,int where,sit S)
134 {
135 sit ans;
136 ans=S;
137 cio tmp=ans.c[which];
138 tmp.move(where);
139 for(int others=1;others<=4;others++)
140 {
141 if(others==which)
142 continue;
143 if(tmp==ans.c[others])
144 {
145 tmp.move(where);
146 break;
147 }
148 }
149 for(int others=1;others<=4;others++)
150 {
151 if(others==which)
152 continue;
153 if(tmp==ans.c[others])
154 return anc;
155 }
156 if(check_and_ban(tmp))
157 return anc;
158 ans.c[which]=tmp;
159 return ans;
160 }
161 bool check_and_ban(cio one)
162 {
163 int i=one.i;
164 int j=one.j;
165 if(i<=0||i>8)
166 return true;
167 if(j<=0||j>8)
168 return true;
169 return false;
170 }
171 bool cmp(cio x,cio y)
172 {
173 if(x.i!=y.i)
174 return x.i<y.i;
175 return x.j<y.j;
176 }
177 void sit::sort(void)
178 {
179 std::sort(c+1,c+4+1,cmp);
180 return ;
181 }
182 void cio::move(int direction)
183 {
184 i+=di[direction];
185 j+=dj[direction];
186 return ;
187 }
2.IDDFS
限定层数,本质上是在空间条件下不允许的情况下提高了Dfs的实际效率。
蒟蒻代码不可读
3.A*
类似一种Bfs,对于问题求解时不要求最优时使用,其中有估价函数使算法在接近答案时有较强兴奋性,使得搜索到可行解的概率大大提高。
时间复杂度比较玄学,一般在输出任意解时有用。
蒟蒻代码不可读
4.IDA*
本人最喜欢的搜索,其估价函数用于估计步数,提前结束搜索,减少了很多层,在指数级别优化了算法。