1
在 3 X 3 的空格内,用1,2,…, 9 的9个数字填入9个空格内,使得每行数字组成的十进制数平方根为整数。试用一般图搜索搜索算法求解。
解题思路
$$$$
\quad
一般图搜索算法可以使用DFS和BFS两种思路来进行状态的求解,由于在本次求解过程中,并没有要求路径最短或是耗散值最小,BFS的优先级并不是很高,并且考虑到BFS在状态分析的过程中占用的空间比较多,所以使用占用空间更少的DFS更加合理
代码
#include<cmath>
#include<iostream>
using namespace std;
int visit[9], arr[9], n = 9;
bool is_sqrt(int num)
{
return pow(int(sqrt(num)),2) == num;
}//返回条件判定
void dfs(int count)
{
if(count == n)//1 判定是否到达dfs下线
{
int fir = arr[0] * 100 + arr[1] * 10 + arr[2];
int sec = arr[3] * 100 + arr[4] * 10 + arr[5];
int thi = arr[6] * 100 + arr[7] * 10 + arr[8];
if(is_sqrt(fir)&&is_sqrt(sec)&&is_sqrt(thi))// 1.1 判定是否满足输出条件
{
for(int j = 0; j < int(sqrt(n)); j++)
{
for(int i = 0; i < int(sqrt(n)); i++)
cout << arr[i+3*j] ;
cout << endl;
}
cout << endl;
}
return;
}
for(int i = 0; i < n; i++)//2遍历
{
if(visit[i])//dfs入栈判定
continue;
visit[i] = 1;//入栈
arr[count] = i + 1;//入栈,需要注意题目是从1到9而不是从0到8
dfs(count + 1);//入栈+出栈
visit[i] = 0;//出栈
}
}
int main()
{
dfs(0);
return 0;
}
2
分析宽度优先搜索和深度优先搜索的优缺点,举出他们的正例和反例。
宽度优先搜索 | 深度优先搜索 | |
---|---|---|
优点 | 可以较为简单的获取符合要求且耗散值最小的路径。并且不需要再次回溯进行状态更新 | 在只需要一组解的时候效率较高。并且可以通过适当的if else语句提高效率,并且一般只有一个栈的进程,占用空间比较少 |
缺点 | 当所求状态深度比较大的时候,会占用大量的空间和实践在深度较浅的状态 | 搜索到符合的目标状态不一定是耗散值最小的,需要将所有符合目标的状态都遍历一遍才能获得最佳状态 |
大部分情况下可以说BFS的正例刚好是DFS的反例,DFS正例也是BFS反例
优先考虑BFS的例子:EOJ上的第一题【八数码问题】就很合适用BFS探索通过最短的路径状态
优先考虑DFS的例子:本次作业第一题
3
有一个农夫带一只狐狸、一只小羊和一个菜篮过河。假设农夫每次只能带一样东西过河,考虑安全,无农夫看管时,狐狸和小羊不能在一起,小羊和菜篮不能在一起。试设计求解该问题的状态空间,并画出状态空间图。
(1)定义状态空间
令狐狸,小羊,菜篮,农夫分别初始化为A,B,C,D
状态表现形式 (A = ?, B = ?, C = ?, D = ?)
初始状态 (A = 0, B = 0, C = 0, D = 0)
目标状态 (A = 1, B = 1, C = 1, D = 1)
(2)定义操作
OP1 (!A 且 !D) (当A⊙D == true)
OP2 (!B 且 !D) (当B⊙D == true)
OP3 (!C 且 !D) (当C⊙D == true)
OP4 (!D)
(3)条件限制
令ABCD排列为二进制数
不可以出现ABCD二进制数转化为十进制的1 3 6 9 12 14的情况
并且不应该重复出现已出现过的情况
0001
0011
0110
1001
1100
1110