6.方格填数

方格填数

如下的10个格子

在这里插入图片描述

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

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

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

解析

C++题解

方法一

将该10个格子按顺序拉成一个一维数组,然后将十个数字填进去(全排列),填完之后进行判断即可。

 #include <bits/stdc++.h>
  using namespace std;
  
  int a[11], Ans;
  
  int calc(int x, int y) {
      return abs(a[x]-a[y]);
 }
  
 bool check() {
     if(calc(0, 1) == 1) return false;
     if(calc(0, 3) == 1) return false;
     if(calc(0, 4) == 1) return false;
    if(calc(0, 5) == 1) return false;
     
     if(calc(1, 2) == 1) return false;
     if(calc(1, 4) == 1) return false;
     if(calc(1, 5) == 1) return false;
     if(calc(1, 6) == 1) return false;
 
     if(calc(2, 5) == 1) return false;
    if(calc(2, 6) == 1) return false;
     
     if(calc(3, 4) == 1) return false;
     if(calc(3, 7) == 1) return false;
     if(calc(3, 8) == 1) return false;
    
    if(calc(4, 5) == 1) return false;
    if(calc(4, 7) == 1) return false;
     if(calc(4, 8) == 1) return false;
     if(calc(4, 9) == 1) return false;
     
     if(calc(5, 6) == 1) return false;
     if(calc(5, 8) == 1) return false;
     if(calc(5, 9) == 1) return false;
    
     if(calc(6, 9) == 1) return false;
     if(calc(7, 8) == 1) return false;
     if(calc(8, 9) == 1) return false;
     return true;
 }
 
 void dfs(int pos) {
     if(pos == 10) {
         if(check()) Ans ++;
         return ;
     }
     for(int i=pos; i<10; ++i) {
         int t = a[pos]; a[pos] = a[i]; a[i] = t;
         dfs(pos+1);
         t = a[pos]; a[pos] = a[i]; a[i] = t;
     }
 }
 
 int main() {
     for(int i=0; i<=10; ++i)
         a[i] = i;
     dfs(0);
     printf("%d\n", Ans);
     return 0;
 }

方法二

在原图的基础上加一圈,然后判断。这个方法的check函数较为简洁。初始化可以不是-10,只要不与0-9相差±1即可。

 #include <bits/stdc++.h>
 using namespace std;
 
  int Map[5][6], Ans;
  bool vis[10];
  
 bool check(int x, int y) {
      for(int i=x-1; i<=x+1; ++i) {
          for(int j=y-1; j<=y+1; ++j) {
           if(abs(Map[x][y]-Map[i][j]) == 1) 
                 return false;  
         }
     }
     return true;
 }
 
 void dfs(int x, int y) {
     if(x==3 && y==4) {
         Ans++;
        return ;
     }
     for(int i=0; i<10; ++i) {
         if(vis[i]) continue; //这个数字用了
         Map[x][y] = i; // 先放着 
         if(!check(x, y)) {
             Map[x][y] = -10; // 
             continue; //放下不符规则
         }
         vis[i] = true;
         if(y == 4) 
             dfs(x+1, 1); // 换行 
         else dfs(x, y+1); // 右边的格子
        Map[x][y] = -10; // 回溯 
         vis[i] = false; 
    }
 }
 
 int main() {
     for(int i=0; i<10; ++i) vis[i] = false;
     for(int i=0; i<5; ++i) // 外面加一圈 
         for(int j=0; j<6; ++j)
             Map[i][j] = -10;
     dfs(1, 2); //第一个填数的格子是(1,2) 
     printf("%d\n", Ans);
     return 0;
 }

如图:
在这里插入图片描述

Java题解

public class _06方格填数 {
 
	public static void main(String[] args) {
		dfs(0);
		System.out.println(ans);
	}
	
	static int[] a = new int[] {0,1,2,3,4,5,6,7,8,9};
	static int ans=0;
	
	static void dfs(int m) {
		if(m>=10) {
			if(a[0]==a[1]-1 || a[0]==a[1]+1 || a[0]==a[4]-1 || a[0]==a[4]+1 || a[0]==a[3]-1 || a[0]==a[3]+1 || a[0]==a[5]-1 || a[0]==a[5]+1)
				return;
			if(a[1]==a[2]-1 || a[1]==a[2]+1 || a[1]==a[5]-1 || a[1]==a[5]+1 || a[1]==a[4]-1 || a[1]==a[4]+1 || a[1]==a[6]-1 || a[1]==a[6]+1)
				return;
			if(a[2]==a[6]-1 || a[2]==a[6]+1 || a[2]==a[5]-1 || a[2]==a[5]+1)
				return;
			if(a[3]==a[4]-1 || a[3]==a[4]+1 || a[3]==a[7]-1 || a[3]==a[7]+1 || a[3]==a[8]-1 || a[3]==a[8]+1)
				return;			
			if(a[4]==a[5]-1 || a[4]==a[5]+1 || a[4]==a[8]-1 || a[4]==a[8]+1 || a[4]==a[7]-1 || a[4]==a[7]+1 || a[4]==a[9]-1 || a[4]==a[9]+1)
				return;					
			if(a[5]==a[6]-1 || a[5]==a[6]+1 || a[5]==a[8]-1 || a[5]==a[8]+1 || a[5]==a[9]-1 || a[5]==a[9]+1)
				return;
			if(a[6]==a[9]-1 || a[6]==a[9]+1 || a[7]==a[8]-1 || a[7]==a[8]+1 || a[8]==a[9]-1 || a[8]==a[9]+1)
				return;	
			for(int i=0;i<=9;i++)
				System.out.print(a[i]+" ");
			System.out.println();
			ans++;
			return;
		}
		
		for(int i=m;i<10;i++) {
			swap(m,i);
			dfs(m+1);
			swap(m,i);
		}
		
	}
	
	static void swap(int i,int j) {
		int t = a[i];
		a[i] = a[j];
		a[j] = t;
	}
 
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值