蓝桥旧题_数字填充问题

问题:方格填数
如下的10个格子
±-±-±-+
| | | |
±-±-±-±-+
| | | | |
±-±-±-±-+
| | | |
±-±-±-+
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
思考:方格填数问题与四皇后问题类似 ;(运用回溯法的思想)
一,可以理解为有一个三行四列的数组;
(当然,题目中没有格子的地方可以理解为该位置不能够放置数字)
二,运用回溯法思想:
1,设置一个三行四列的数组,给他们初始化的时候避免出现题中0到9产生混淆,其中不能存放数字的地方与其
余初始化区别开,方便以后条件判断
2,先考虑第一列的三个位置,然后第一列的每一个位置在延申到第二列,这样就遍历了所有的情况。
3,数字不能重复我设置了一个能存放十个数字的数组,每次用后设置标志位1,然后遍历完所有表格一次清零;
4,不能相邻问题我用了一个方法,通过对数组左右,上下,对角线分别进行条件判断,当然,不能放置数字的;
位置初始化较大,不会与其余空格有连续情况影响;

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int sum=0;
int h[10]={0}; 
int m(int (*s)[4],int i,int j){                                //判断该位置是否可以放置数据 
	for(i=0;i<3;i++){
		for(j=0;j<4;j++){
			if(s[i][j]==100){
				return 1;
			}
			else{
				return 0;
			}
		}
	}
}

int isplace(int a[3][4],int i,int j){                             //断空格的当前位置能否放置该数据 
		if(j>=1){
			if(abs(a[i][j]-a[i][j-1])==1){                                         //水平左边 
				return 0;
			}
		}		
		if(j<=2){
			if(abs(a[i][j]-a[i][j+1]==1)){                                         //水平右边 
				return 0;
			}
		}		
		if(i>=1){                                                                  //垂直上端 
			if(abs(a[i][j]-a[i-1][j]==1)){
				return 0;
			}
		} 		
		if(i<=1){                                                                 //垂直下端 
			if(abs(a[i][j]-a[i+1][j]==1)){
				return 0;
			}
		}		
		if((i>=1)&&(j>=1)){                                                       //对角线左上 
			if(abs(a[i][j]-a[i-1][j-1]==1)){
				return 0;
			}
		}		
		if((i<=1)&&(j<=2)){                                                       //对角线右下 
			if(abs(a[i][j]-a[i+1][j+1]==1)){
				return 0;
			}
		}		
		if((i>=1)&&(j<=2)){                                                       //对角线右上 
			if(abs(a[i][j]-a[i-1][j+1]==1)){
				return 0;
			}
		}		
		if((i<=1)&&(j>=1)){                                                       //对角线左下 
			if(abs(a[i][j]-a[i+1][j-1]==1)){
				return 0;
			}
		}
	return 1;  		
}

void dfs(int s[3][4],int k){                                //三行四列 
	int i,j,l;	
	int f,n; 
	if((i==2)&&(k==3)){                                  //遍历完题中给出方格布局的最后一个位置,递归出口 
		sum++;
		for(j=0;j<=9;j++){                             //第一次所有情况遍历完数字使用记录清零; 
			h[j]=0;
		}
	
		for(f=0;f<3;f++){                               //遍历完一次再次初始化 
			for(n=0;n<4;n++){
				s[i][j]=100;
			}
		}
		s[0][0]=99;
		s[2][3]=99;                    			
		return ;                                        //一次遍历结束 
	}
	for(i=0;i<3;i++){                                  //遍历第一列的每个元素 
		if(m(s,i,k)){
			for(l=0;l<=9;l++){                         //保证不重复也是个问题 :这里需要一个存放0到9是个元素的数组 
				s[i][k]=l;				
				if(isplace(s,i,k)&&h[l]==0)    h[l]=1;    break;	
			}	
		}
	dfs(s,k+1);				
	}	
}
int main(int argc, char *argv[]) {
	int a[3][4];
	int i,j,k=0;
	for(i=0;i<3;i++){
		for(j=0;j<4;j++){
			a[i][j]=100;
		}
	}
	a[0][0]=99;
	a[2][3]=99;                     //以上两个位置表示不可以放置数据
	dfs(a,0); 
	printf("%d",sum);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值