总结
这次,我们来看看搜索的题目。
上次没来得及写。
题目
设有n个整数的集合{1,2,…,n},从中取出任意r个数进行排列(r<n),试列出所有的排列。
这是ppt上的题目,理解起来挺简单的。
#include<cstdio>
#include<iostream>
#include<iomanip>
using namespace std;
int num=0,a[10001]={0},n,r;
bool b[10001]={0};
int search(int k)//回溯过程
{
int i;
for (i=1;i<=n;i++)//有n种可能
if (!b[i]) //判断i是否可用
{
a[k]=i; //保存结果
b[i]=1;//标志i已经填过;
if (k==r) print();//如果填完,输出
else search(k+1);//否则 填下一个
b[i]=0; //回档
}
}
int print()//输出
{
num++;
for (int i=1;i<=r;i++)
cout<<setw(3)<<a[i];
cout<<endl;
}
int main()
{
cin>>n>>r;//从n个数中选r个数;
search(1);//就是有r个位置,从n中个数选择数字来填,从第一个开始;
cout<<num<<endl; //输出方案总数
}
跳马问题。在5*5格的棋盘上,有一只中国象棋的马,从(1,1)点出发,按日字跳马,它可以朝8个方向跳,但不允许出界或跳到已跳过的格子上,要求在跳遍整个棋盘。
输出前5个方案及总方案数。
这个就是找出方案走完整个棋盘。
练习里有个题目和这个很像。
用深度搜索。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<iomanip>
using namespace std;
int u[8]={1,2,2,1,-1,-2,-2,-1}, //8个方向上的x,y增
int v[8]={-2,-1,1,2,2,1,-1,-2};
int a[100][100]={0},num=0; //记每一步走在棋盘的哪一格和棋盘的每一格有没有被走过
bool b[100][100]={0};
int search(int,int,int); //以每一格为阶段,在每一阶段中试遍8个方向
int print(); //打印方案
int main()
{
a[1][1]=1;b[1][1]=1; //从(1,1)第一步开始走
search(1,1,2); //从(1,1)开始搜第2步该怎样走
cout<<num<<endl; //输出总方案(304)
}
int search(int i,int j,int n)
{
int k,x,y;
if (n>25) {print();return 0;} //达到最大规模打印、统计方案
for (k=0;k<=7;k++) //试遍8个方向
{
x=i+u[k];y=j+v[k]; //走此方向,得到的新坐标
if (x<=5&&x>=1&&y<=5&&y>=1&&(!b[x][y]))
{//如果新坐标在棋盘上,并且这一格可以走
b[x][y]=1;
a[x][y]=n;
search(x,y,n+1); //从(x,y)去搜下一步该如何走
b[x][y]=0;
}
}
}
int print()
{
num++; //统计总方案
if (num<=5) //打印出前5种方案
{
for (int k=1;k<=5;k++) //打印本次方案
{
for (int kk=1;kk<=5;kk++)
cout<<setw(5)<<a[k][kk];
cout<<endl;
}
}
}
感慨
先来这两个。
不需要太费脑子的。
看着解析一会就明白了。
其他的我再看看。
话说肩膀疼的要死。
可能是拉伤了。。。