排座位

/*  排座位 
 要安排:3个A国人,3个B国人,3个C国人坐成一排。 
 要求不能使连续的3个人是同一个国籍。 
 求所有不同方案的总数? 
 */
/*public class 排座位 {
	public static char[] c = {'A','A','A','B','B','B','C','C','C'}; 
	public static int kinds= 0; // 不同方案总个数  
    // 检查是否有同一国人连续3个  
    public static boolean check(char[] c){  
        int count = 1;  // 初始个数  
        for(int i=0;i<c.length-1;i++){  
            if(c[i]==c[i+1]){  
                count++;  
            }else{  
                count = 1;  // 初始个数  
            }  
            if(count>=3) return true;  
        }  
        return false;  
    }  
    // 全排列  
    public static void f(char[] c,int start,int end){  
        if(start == end){  
            if(!check(c)){  // 检查是否有同一国人连续3个  
                kinds++;      // 不同方案总个数加1  
            }  
            return ;  
        }else{  
            for(int i=start;i<=end;i++){  
                char temp = c[i];  
                c[i] = c[start];  
                c[start] = temp;  
                f(c,start+1,end); // 递归  
                temp = c[i];  
                c[i] = c[start];  
                c[start] = temp;  
            }  
        }  
    }  
    public static void main(String[] args){  
        f(c,0,c.length-1);    // 全排列  
        System.out.println("kinds:"+kinds);  
    }  
}
*/
方法二
public class 排座位 
{  
    public static int kinds=0;  
    public static int b[]=new int[9];  
    public static boolean vis[]=new boolean[9]; 
    public static int a[]=new int[]{1,1,1,2,2,2,3,3,3}; 
    static void dfs(int start,int end)  
    {  
        if(start==end)  
        {  
            kinds++;  
        }  
        else  
        {  
            for(int i=0;i<a.length;i++)  
            {  
                if(!vis[i])//未上坐  
                {  
                    b[start]=a[i];  
                    if(start>1 && b[start-2]==b[start-1] && b[start-1]==b[start])   
                        continue;//边排边检查提高效率  
                    vis[i]=true;  
                    dfs(start+1,end);  
                    vis[i]=false;  
                }  
            }  
        }  
    } 
    public static void main(String[] args)  
    {    
        dfs(0,a.length);  
        System.out.println("kinds:"+kinds);  
    } 
}
运行结果:
kinds:283824
扩展:
如果每个国家的三个人是可重复的,即来自同一个国家的三个人是不区分的,所以序列是可以重复的。
程序如下:
import java.util.Arrays;  
public class 排座位    
{  
    static int kinds=0;  
    static int a[]=new int[4];  
    static int b[]=new int[4];  
    static int c[]=new int[4];  
    static int aim[]=new int[10];  
    public static void main(String[] args)  
    {  
        Arrays.fill(a,1);  
        Arrays.fill(b,2);  
        Arrays.fill(c,3);
        dfs(1,3,3,3);  
        System.out.println("kinds:"+kinds);  
    }  
    static void dfs(int start,int a,int b,int c)  
    {  
        if(start==10)  
        {  
            kinds++;  
            for(int i=1;i<start;i++)  
            {  
                System.out.printf("%c",(aim[i]+64));  
            }  
            System.out.println();  
        }  
        else if(start<3)//肯定不会出现三个座来自国家相同的,因为就两座位。 
        {  
            aim[start]=1;  
            a--;  
            dfs(start+1,a,b,c);  
            a++;  
              
            aim[start]=2;  
            b--;  
            dfs(start+1,a,b,c);  
            b++;  
              
            aim[start]=3;  
            c--;  
            dfs(start+1,a,b,c);  
            c++;  
        }  
        else  
        {  
            aim[start]=1;  
            if(!(aim[start-2]==aim[start-1] && aim[start-1]==aim[start]) && a>0)//不是3连号,且A国家还有人未上坐  
            {  
                a--;  
                dfs(start+1,a,b,c);  
                a++;  
            }  
              
            aim[start]=2;  
            if(!(aim[start-2]==aim[start-1] && aim[start-1]==aim[start]) && b>0)//同理  
            {  
                b--;  
                dfs(start+1,a,b,c);  
                b++;  
            }  
              
            aim[start]=3;  
            if(!(aim[start-2]==aim[start-1] && aim[start-1]==aim[start])  && c>0)//同理  
            {  
                c--;  
                dfs(start+1,a,b,c);  
                c++;  
            }  
        }  
    }  
}
运行结果为(部分结果):
CCBBAABCA
CCBBAACAB
CCBBAACBA
CCBBABAAC
CCBBABACA
CCBBABCAA
CCBBACAAB
CCBBACABA
CCBBACBAA
CCBBCAABA
CCBBCABAA
CCBCAABAB
CCBCAABBA
CCBCABAAB
CCBCABABA
CCBCABBAA
CCBCBAABA
CCBCBABAA
kinds:1314

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值