2018年4月27日

总结

这次,我们来看看搜索的题目。
上次没来得及写。

题目

设有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;  
        }
    }
}

感慨

先来这两个。
不需要太费脑子的。
看着解析一会就明白了。
其他的我再看看。
话说肩膀疼的要死。
可能是拉伤了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值