第七届蓝桥杯java B组试题题解(仅代表个人观点)

本文介绍了一种解决方格填数问题的算法实现,该问题要求在特定的方格中填入0~9的数字,并确保连续数字不相邻。通过使用全排列和递归方法,文章详细解释了如何计算所有可能的填数方案。

第六题:方格填数

如下的10个格子

| 这里写图片描述

#

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
(1580种)

public  class Main
{   
    //将前后几个方法中都要用到的变量全部设为全局变量
    static int a[][]=new int[5][6];//此处是将原图外围再包上一圈,
                    //将原图中的边界元素
                    //变成非边界元素,以使原图中
                    //的边界元素避免麻烦的边界处理。
                    //然后用二维数组a进行表达以方便后续处理。
    static int []data={0,1,2,3,4,5,6,7,8,9};
    static int count=0;//存储总的方案数

    public static void main(String args[])
    {   
        //先将数组a赋初值,且这个初值应远离0-9中任何
        //一个数,后续只对
        //除边界以外的数组元素进行赋值,则可默认边界
        //不可能会与其他元素相邻。

        for(int i=0;i<5;i++)
        {
            for(int j=0;j<6;j++)
            {
                a[i][j]=-2;
            }
        }

        get_fullpermutation(data, 0);
        System.out.print(count);
    }

    //对一种全排列情况进行判断
    public static boolean judge(int [][]v)
    {
        for(int i=1;i<=3;i++)
        {
            for(int j=1;j<=4;j++)
            {
                if(i==1&&j==1||i==3&&j==4)
                {
                    continue;
                }
                int x=v[i][j]+1;
                int y=v[i][j]-1;
                if(x==v[i+1][j]||x==v[i-1][j]||x==v[i][j+1]||
                    x==v[i][j-1]||x==v[i+1][j+1]||
                        x==v[i-1][j-1]||
                    x==v[i+1][j-1]||
                    x==v[i-1][j+1])
                {
                    return false;
                }
                if(y==v[i+1][j]||y==v[i-1][j]||y==v[i][j+1]||
                    y==v[i][j-1]||y==v[i+1][j+1]||
                        y==v[i-1][j-1]||
                        y==v[i+1][j-1]||
                    y==v[i-1][j+1])
                {
                    return false;
                }
            }
        }
        return true;
    }

    //得到0-9的全排列并将其赋值于数组a,
    public static void  get_fullpermutation(int []d,int k)
    {
        if(k==d.length)//每得到一种全排列就赋值一次并进行判断
        {
            int t=0;
            for(int i=1;i<=3;i++)
            {
                for(int j=1;j<=4;j++)
                {
                    if(i==1&&j==1||i==3&&j==4)
                    {
                        continue;
                    }
                    else
                    {
                        a[i][j]=data[t];
                        t++;
                    }
                }
            }
            if(judge(a))//judge函数返回true时即连续的两个数字不相邻
            {
                count++;
            }

        }

        //全排列
        for(int i=k;i<d.length;i++)
        {
            {int t=d[i];d[i]=d[k];d[k]=t;}
            get_fullpermutation(d, k+1);
            {int t=d[i];d[i]=d[k];d[k]=t;}
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值