Ch2习题
1、 在 3 X 3 的空格内,用1,2,…, 9 的9个数字填入9个空格内,使得每行数字组成的十进制数平方根为整数。试用一般图搜索搜索算法求解。
解:
思路:
一共有9!次填法情况。数据庞大,需要考虑如何进行剪枝优化,第一行不满足情况,就可以直接进行回溯直到第一行满足,才进行到第二行的搜索。
#include<bits/stdc++.h>
using namespace std;
bool is_square(int n)
{
int root=(int)sqrt(n);
return root*root==n;
}
vector<int> ans;
vector<int>nums(10);
vector<int> visited(10,0);
bool dfs(int count)
{
if (count==9)
{
return true;
}
for(int i=1;i<=9;i++)
{
if(!visited[i])
{
nums[count] =i;
visited[i]=1;
if( count%3==2)//改善count==2||count==5||count==8
{
int n=nums[count-2]*100+nums[count-1]*10+nums[count];
if(is_square(n))
{
if(dfs(count+1))
{
ans.push_back(nums[count-2]);
ans.push_back(nums[count-1]);
ans.push_back(nums[count]);
return true;
}
}
}
else
{
if(dfs(count+1)) return true;
}
visited[i]=0;//这里之前放在大括号外面,导致出错
}
}
return false;
}
int main()
{
dfs(0);
// cout<<ans.size();
for(int i=0;i<=8;i++)
{
cout<<ans[i]<<' ';
if(i%3==2) cout<<endl;
}
system("pause");
return 0;
}
这里提供另外一个优化搜索的预处理手段,是借鉴了我室友的代码,学习到了bitset的用法。
bitset是C++stl模块的一个容器,用于表示一个固定长度的二进制序列,即位集合。可以方便位运算和查询位
#include<bits/stdc++.h>
using namespace std;
vector<int> v,ch(3);//ch是一行的临时数组
vector<bitset<10>> vb;//位串的集合
vector<vector<int>> sol;//解的数组
void dfs(int ind,int cnt,bitset<10> sel)
{
if(cnt==3)sol.push_back(ch);
else for(;ind<v.size();ind++)if((sel|vb[ind]).count()==cnt*3+3)//可以看图1.1确保两行没有相同的数字
{
ch[cnt]=v[ind];
dfs(ind+1,cnt+1,sel|vb[ind]);
}
}//bitset.count()可以计算出二进制串中的1的数量
signed main()
{
int i,j;
bitset<10> b(0);
for(i=11;i<32;i++)
{
j=i*i;
if(j/100==(j/10)%10||j/100==j%10||(j/10)%10==j%10)continue;
v.push_back(j);
vb.push_back(bitset<10>((1<<j/100)+(1<<(j/10)%10)+(1<<j%10)));
}//先进行了预处理,先把3位数中平方数都找到。bitset<n>(a)表示将a转化为n位的二进制串。
dfs(0,0,b);
cout<<6*sol.size()<<"\n\n";
for(auto s:sol)for(i=0;i<3;i++)for(j=0;j<2;j++)
{
cout<<s[0]<<'\n'<<s[1]<<'\n'<<s[2]<<"\n\n";
swap(s[j],s[j+1]);
}
system("pause");
return 0;
}
图1.1
2、分析宽度优先搜索和深度优先搜索的优缺点,举出他们的正例和反例。
宽度优先搜索 | 深度优先搜索 | |
---|---|---|
优点 | BFS方便找到最短路径 可以检测无向图中是否有环 | 在只需要一组解时效率较高 适用于深度较高的问题 |
缺点 | 当所求状态深度较大,会占用大量空间,时间复杂度会比较高。 结点和边数量较多,会大量的重复计算 | 需要求最优解时效率不如宽度优先搜索 asd |
优先考虑BFS的例子:EOJ上的第一题【八数码问题】
优先考虑DFS的例子:本次作业第一题
3、有一个农夫带一只狐狸、一只小羊和一个菜篮过河。假设农夫每次只能带一样东西过河,考虑安全,无农夫看管时,狐狸和小羊不能在一起,小羊和菜篮不能在一起。试设计求解该问题的状态空间,并画出状态空间图。