方格填数

蓝桥杯历年省赛真题汇总及题目详解

2016年第七届蓝桥杯省赛试题详解

方格填数

如下的10个格子
±-±-±-+
| | | |
±-±-±-±-+
| | | | |
±-±-±-±-+
| | | |
±-±-±-+

(如果显示有问题,也可以参看【图1.jpg】)

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
int count=0;
int take[10],index=0;//记录当前已经填入的数字,用于填数字前判断是否已经使用,避免重复使用 
int is_legal(int s[3][4])//判断是否满足要求:相邻位置数字不能相邻,就是两数字的差大于1.就是为什么s[0][0]、s[2][3]置为-2;
{
    //这里的判断方法有点死板。假设每个位置都有上下左右和对角,只需要判断这些位置
    //是不是在数组中,在就进行比较,不在就说明没有。 
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(j-1>=0)
            {
                if(abs(s[i][j]-s[i][j-1])==1)
                {
                    return 0;
                }
            }
            if(j+1<4)
            {
                if(abs(s[i][j]-s[i][j+1])==1)
                {
                    return 0;
                }
            }
            if(i+1<3)
            {
                if(abs(s[i][j]-s[i+1][j])==1)
                {
                    return 0;
                }
            }
            if(j-1>=0&&i+1<3)
            {
                if(abs(s[i][j]-s[i+1][j-1])==1)
                {
                    return 0;
                }
            }
            if(j+1<4&&i+1<3)
            {
                if(abs(s[i][j]-s[i+1][j+1])==1)
                {
                    return 0;
                }
            }
            if(i-1>=0&&j+1<4)
            {
                if(abs(s[i][j]-s[i-1][j+1])==1)
                {
                    return 0;
                }
            }
            if(i-1>=0)
            {
                if(abs(s[i][j]-s[i-1][j])==1)
                {
                    return 0;
                }
            }
            if(j-1>=0&&i-1>=0)
            {
                if(abs(s[i][j]-s[i-1][j-1])==1)
                {
                    return 0;
                }
            }
        }
    } 
    return 1;
}
void fun(int s[3][4],int a,int b)
{
    int i;
    if(a==2&&b==3)//表示当前已经填满了表格,需要进行判断看是否满足要求 
    {
        if(is_legal(s))
        {
            count++;
        }
    }
    else//继续填写 
    {
        for(i=0;i<=9;i++)
        {
            int j;
            for(j=0;j<index;j++)//填写的数字必须是没有用过的 
            {
                if(i==take[j])
                {
                    break;
                }
            }
            if(j==index)
            {
                s[a][b]=i;
                take[index++]=i;
                if(b<3)//表示当前行还没填完 
                {
                    fun(s,a,b+1);
                }
                else//当前行填完就从下一行开始 
                {
                    if(a<2)//判断当前行是否是最后一行 
                    {
                        fun(s,a+1,0);
                    }
                }
                index--;//在一次填满结束后,当前位置的数字换为其他可以填写的数字
                        //所以当前使用的数字需要出去。 
            }
        } 
    }
}
int main()
{
    int s[3][4];
    s[0][0]=-2;
    s[2][3]=-2;
    //左上角和右下角没有,为了方便判断把数值设为-2(小于-1大于10均可) 
    fun(s,0,1);
    printf("%d\n",count);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值