5-29 完备环序列问题
问题描述
长度为 n 的环序列定义为含有 n 个互不相同的元素且首尾相接的环状序列。如果环序列中连续若干个数的和能形成一个连续的整数序列 1,2,…,m,则称该环序列为一个完备的 (n,m)序列。对于给定的 n,计算存在完备(n,m)序列的 m 的最大值。同时,计算出有多少个 不同的完备(n,m)序列。
对于给定的正整数 n,计算存在完备(n,m)序列的 m 的最大值;计算有多少个不同的完 备(n,m)序列。
数据输入:
第一行有 1 个正整数 n,1≤n≤10。
Java
package Chapter5HuiSuFa;
import java.util.Scanner;
public class WanBeiHuanXuLie {
private static int n,r,maxi;
private static int[] a,b,t;
private static int[][] f;
private static int count;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
count = 0;
maxi = 0;
n = input.nextInt();
r = n*(n-1)+1;
a = new int[n+1];
b = new int[r+1];
t = new int[r+1];
f = new int[20][n+1];
for(int i=0; i<=r; i++)
b[i] = 0;
a[1]=1; b[1]=1;
backtrack(2);
if(maxi < r){
r = maxi;
backtrack(2);
}
out();
}
}
private static void backtrack(int m){
int y = r;
for(int x=1; x<=m-1; x++)
y -= a[x];
for(int x=2; x<=y; x++)
if(b[x] == 0){
a[m]=x; b[x]=1;
if(m == n) {if(oka()) ans();}
else backtrack(m+1);
b[x] = 0;
}
}
private static boolean oka(){
for(int i=1; i<=r; i++)
t[i] = 0;
for(int i=1; i<=n; i++){
int k = a[i];
t[k] = 1;
for(int j=1; j<=n-1; j++){
if(i+j <= n) k+=a[i+j];
else k+=a[i+j-n];
t[k]=1;
}
}
for(int i=1; i<=r; i++)
if(t[i] == 0){
if(maxi < i-1) maxi = i-1;
return false;
}
maxi = r;
return true;
}
private static void ans(){
for(int i=1; i<=n; i++) f[count][i]=a[i];
count++;
}
private static void out(){
System.out.println(r+" "+count);
for(int i=0; i<count; i++){
for(int j=1; j<=n; j++)
System.out.print(f[i][j]+" ");
System.out.println();
}
}
}
Input & Output
2
3 1
1 2
5
21 2
1 3 10 2 5
1 5 2 10 3
Reference
王晓东《计算机算法设计与分析》