算法设计与分析: 5-29 完备环序列问题

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

王晓东《计算机算法设计与分析》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值