方格填数 蓝桥杯

题目描述

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

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

输出方案总数即可。这里写图片描述

开始题意理解错了,以为每个数字用的次数不限,错了,是每个数字只用一次

方一:

#include<stdio.h>
#include<math.h>
#include<string.h>

struct Direction{ 
    int x;
    int y;
};
struct Direction d[4]={{0,-1},{-1,-1},{-1,0},{-1,1}};//只检查这四个方向,别的四个方向还没有填数 
int a[5][6],vis[11],sum=0;

judge(int k,int i,int j){
      int l;
      for(l=0;l<4;l++){
        if(abs(k-a[i+d[l].x][j+d[l].y])==1) return 0;
      }
      return 1;
}

dfs(int l,int n){//一次确定一个位置可能填的数字 
    int i,j,k;
    if(l==n){
        sum++;
        return 0;
    }
    else{
        for(i=1;i<4;i++){
            for(j=1;j<5;j++){
                if(a[i][j]!=-2)continue;
                for(k=0;k<=9;k++){
                    if(vis[k]==0&&judge(k,i,j)==1){
                        a[i][j]=k;
                        vis[k]=1;
                        dfs(l+1,n);//继续填下一个空格 
                        //将该位置还原,该位置还可能放别的数 
                        a[i][j]=-2; 
                        vis[k]=0;
                    }
                }
                return 0;//这里很重要,如果不返回,则接下来就去别的空格了,而每一次只填一个空格,就乱了 
            }
        }
    }

}

int main(){
    int i,j,k;
    memset(vis,0,sizeof(vis));
    for(i=0;i<5;i++){
        for(j=0;j<6;j++){
            if(i==0||j==0||i==4||j==5){
                a[i][j]=-3;
            }
            else a[i][j]=-2;
        }
    }
    a[1][1]=-3;a[3][4]=-3;
    dfs(0,10);
    printf("%d",sum);
    return 0;
} 

方二:

#include<stdio.h>
#include<string.h>
#include<math.h>
int a[5][6],res=0,vis[10];
struct D{
    int x;
    int y;
};
struct D d[4]={{0,-1},{-1,-1},{-1,0},{-1,1}};//判断这四个方向上是否有相邻的数字

int jugde(int k,int i,int j){
    int l;
    for(l=0;l<4;l++){//判断这四个方向上是否有相邻的数字
        if(abs(k-a[i+d[l].x][j+d[l].y])==1) return 0;
    }
    return 1;
}

int dfs(int i,int j){
    int k;
    if(i==3&&j==4){//能到这个方格方案数就加1 
        res++;
        return 0;
    }
    else{
        if(j==5){//一行的空格填完填下一行 
            dfs(i+1,1);
        }
        else{
            for(k=0;k<10;k++){
                if(vis[k]==0&&jugde(k,i,j)==1){
                    a[i][j]=k;
                    vis[k]=1;
                    dfs(i,j+1);//继续填下一个位置
                    //将该空格还原,该空格还可能放别的数
                    vis[k]=0;
                    a[i][j]=-1;
                }
            }
        }
    }
}

int main(){
    int i,j,k;
    for(i=0;i<5;i++){
        for(j=0;j<6;j++){
            if(i==0||j==0||i==4||j==5){
                a[i][j]=-2;
            }
            else a[i][j]=-1;
        }
    }
    a[1][1]=-2;a[3][4]=-2;
    dfs(1,2);
    printf("%d",res);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值