c++实现递归的递归

    最近做了一道题,原来题目是这样的: 对于一个给定的n=4(或者n=9)的二维数组,要求其行列只包含1,2,3,4的一个任意组合, 并且要求在其所分割的m*m1(m*m1=n)的二维数组中同样包含一个1,2,3,4个任意的组合,并输出其符合条件的组合 如:

    1 2 3 4

    4 3 1 2

    3 4 2 1

    2 1 4 3

 

一下是源代码,还能优化,

 

#include <iostream>
#include<math.h>
using namespace std;
const int n=4;
int i1=0;
int mn1=1;

class Matrix
{
public:
 Matrix(){
  for (int i=0;i<n;i++)
   a[i] = i+1;
 }
 
 void Perm(int k,int m); //实现全排序 
 void Perm1();  //进行第二次全排序

protected:
 bool Check();  //检查是否满足列条件
 bool Check1(); //判断是否满足分割矩阵的条件
 void Mcheck(int i3,int j1,int k1,int l2,int i,int j,int k,int l,long & mn);
 void swap(int x,int y); //交换数字
 void print1(); //输出最后结果

private:
 int a[n];         //用于存放开始的数字
 int b[24][n];     //用于存放排列成的各行
 int a1[n][n];     //用于形成最后需判断的数组
};

//循环的个数根据 n 的数目进行变化,与n相等
void Matrix::Perm1()   
{
 int i,j,k,l;
 long int count=0;
 for(i=0;i<6;i++)
  for(j=6;j<12;j++)
   for(k=12;k<18;k++)
    for(l=18;l<24;l++)
    {
     for(int jh=0;jh<24;jh++)
     Mcheck(b[jh][0]-1,b[jh][1]-1,b[jh][2]-1,b[jh][3]-1,i,j,k,l,count);
    }  
}

// 进行行列交换的比较
void Matrix::Mcheck(int i3,int j1,int k1,int l2,int i,int j,int k,int l,long & mn)
{
 for(int l1=0;l1<n;l1++)
 {
     a1[i3][l1]=b[i][l1];
     a1[j1][l1]=b[j][l1];
     a1[k1][l1]=b[k][l1];
     a1[l2][l1]=b[l][l1];
 }
 if(Check() && Check1())
 {
     cout<<"符合要求的组合:("<<mn+1<<"):  "<<endl;
     mn++;
     print1();

     if(mn%20==0){cout<<"请按任意键输出第"<<++mn1<<"组...";getchar();}
 }

}

// 实现数据交换
void Matrix::swap(int x,int y)
{
 int temp = a[x];
 a[x] = a[y];
 a[y] = temp;
}

// 实现全排序
void Matrix::Perm(int k,int m)
{
 if ( k ==m)
 {
  for(int i=0;i<=m;i++)
  b[i1][i]=a[i];
  i1++;
 }
 else
 {
  for (int j =k;j<=m;j++)
  {
  swap(k,j);
  Perm(k+1,m);
  swap(k,j);
  }
 }
}

void Matrix::print1()
{
 for(int i=0;i<n;i++)
 {  
  for(int j=0;j<n;j++)
   cout<<a1[i][j]<<" ";
  cout<<endl;
 }
 cout<<endl;
}

//检查是否满足列条件
bool Matrix::Check() 
{
 int k;
 for(int i=0;i<n;i++)
  for(int j=0;j<n-1;j++)
   for(k=j+1;k<n;k++)
   {
    if(a1[j][i]==a1[k][i])return false;
   }
 if(i==n && k==n)return true;
}

//判断是否满足分割矩阵的条件
bool Matrix::Check1()
{
 for(int i=0;i<n;i+=sqrt(n))
  for(int j=0;j<n;j+=sqrt(n))
   if(a1[i][j]==a1[i][j+1]||a1[i][j]==a1[i+1][j]
                           ||a1[i][j]==a1[i+1][j+1]||a1[i][j+1]==a1[i+1][j]
                           ||a1[i][j+1]==a1[i+1][j+1]||a1[i+1][j]==a1[i+1][j+1] )
    return false;
 return true;
}

int main()

 Matrix mat;
 mat.Perm(0,n-1);
 mat.Perm1();
 
 cout<<"请按任意键继续...";
 getchar();
 return 0;
}

 

    从中更加深层到的了解了递归的原理,同时对于全排列的问题的解法有了举一反三的方法,并且学会了回溯法的基本用法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值