#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
const int MAX = 50;
int num = 0; //不同的完备环序列个数
int x[MAX]; //完备环序列
int bestx[20][MAX];
int used[MAX]; //标记数字是否用过
int exist[MAX]; //标记和是否存在
int n;
int bestm;
int m; //能产生的连续整数列的最大值
int r; //长度为n的环序列最多可以产生的不同数字个数
//判断产生的整数是否为连续整数序列
bool ok()
{
memset(exist, 0, sizeof(exist));
int i, k;
for(i=1; i<=n; i++) //寻找所有产生的整数
{
k = x[i];
exist[k] = 1;
for(int j=1; j<n; j++)
{
if(j+i<=n) //序列是一个环
k += x[i+j];
else
k += x[i+j-n];
exist[k] = 1;
}
}
for(i=1; i<=r; i++) //判断是否连续
if(exist[i] == 0)
{
if(m < i-1)
m = i-1; //记录最大连续序列长度
return false;
}
m = r;
return true;
}
void ans()
{
for(int i=1; i<=n; i++)
bestx[num][i] = x[i];
num++;
}
void backtrack(int dep)
{
int y = r;
int i;
for(i=1; i<=dep-1; i++)
y -= x[i];
for(i=2; i<=y; i++)
if(used[i] == 0) //没有用过
{
x[dep] = i;
used[i] = 1;
if(dep == n)
{
if(ok()) //判断产生的整数是否为连续整数序列
ans(); //记录答案
}
else
backtrack(dep+1);
used[i] = 0;
}
}
int main()
{
ifstream fin("完备环.txt");
cout << "输人正整数:";
fin >> n; cout << n << endl;
r = n * (n-1) + 1; //长度为n的环序列最多可以产生的不同数字个数
memset(used, 0, sizeof(used));
memset(exist, 0, sizeof(exist));
x[1] = 1;
used[1] = 1;
backtrack(2);
if(m < r)
{
r = m;
backtrack(2);
}
cout << "能产生的连续整数列的最大值为:" << r << endl;
cout << "不同的完备环序列个数为:" << num << endl;
cout << "各完备环序列如下:\n";
for(int j=0; j<num; j++)
{
for(int i=1; i<=n; i++)
cout << bestx[j][i] << " ";
cout << endl;
}
cout << endl;
cout << endl;
fin.close();
return 0;
}
完备环序列问题
最新推荐文章于 2020-05-02 22:00:16 发布