最近做了一道题,原来题目是这样的: 对于一个给定的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;
}
从中更加深层到的了解了递归的原理,同时对于全排列的问题的解法有了举一反三的方法,并且学会了回溯法的基本用法。