蓝桥杯数独


你一定听说过“数独”游戏。
如【图1.png】,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复。
数独的答案都是唯一的,所以,多个解也称为无解。
本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目。但对会使用计算机编程的你来说,恐怕易如反掌了。
本题的要求就是输入数独题目,程序输出数独的唯一解。我们保证所有已知数据的格式都是合法的,并且题目有唯一的解。
格式要求,输入9行,每行9个数字,0代表未知,其它数字为已知。
输出9行,每行9个数字表示数独的解。
例如:
输入(即图中题目):
005300000
800000020
070010500
400005300
010070006
003200080
060500009
004000030
000009700
程序应该输出:
145327698
839654127
672918543
496185372
218473956
753296481
367542819
984761235
521839764
再例如,输入:
800000000
003600000
070090200
050007000
000045700
000100030
001000068
008500010
090000400
程序应该输出:
812753649
943682175
675491283
154237896
369845721
287169534
521974368
438526917
796318452
分析:还是深搜的思想。只不过在防止数字的时候稍微处理一下就好了。看代码把
import java.util.*;
public class Main {
	static Scanner in = new Scanner(System.in);
    static int[][] a = new int[10][10];
    //判断是否能满足题目要求的放置
    static boolean IsPalce(int x,int y) {
    	int lt = x/3*3;//确定行起点,并且不能越界,利用整数乘法的整除=性
    	int rt = lt + 3;
    	int lb = y/3*3;//确定列起点
    	int rb = lb + 3;
    	//在同一行不能重复
    	for(int i = 0;i < 9;i++)
    		if(a[x][y] == a[x][i] && y != i)
    			return false;
    	//在同一列不能重复
    	for(int i = 0;i < 9;i++)
    		if(a[x][y] == a[i][y] && x != i )
    			return false;
    	//同一色块即所在小的正方形区域
    	for(int i = lt;i < rt;i++)
    	  for(int j = lb;j < rb;j++)
    		if(a[i][j]==a[x][y] && x!=i && y!=j )
    			return false;
    	
    	return true;
    }
    static void dfs(int sp) {
    	if(sp>=81) {
    		for(int i = 0;i < 9;i++) {
              for(int j = 0;j < 9;j++)
            	   System.out.print(a[i][j]); 
              System.out.println();
            }
    		return;
    	}
    	int row = sp/9;
    	int col = sp%9;
    	if(a[row][col]!=0)
    		dfs(sp+1);
    	else {
    	 for(int i = 1;i <= 9 ;i++) {
    		 a[row][col] = i;
    		 if(IsPalce(row,col))
    		   dfs(sp+1);
    		 a[row][col] = 0;
    	   }
    	 }
    }
    public static void main(String[] args) {
     	String s;
        for(int i = 0;i < 9;i++) {
        	s = in.next();
          for(int j = 0;j < s.length();j++){
        	   a[i][j] = s.charAt(j)-'0';
           } 
        }
    	dfs(0);
    }
}

反思:不知道为什么没得全分,吐血。。。。
再补上简洁的代码,权当学习了:
import java.util.*;
class Node{
	int x,y;

	public Node(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
}
public class Main{
	static Scanner sc = new Scanner(System.in);
	static int m,n,cnt = 0;
	static int [][] map = new int[9][9];
	static int [][] col = new int[9][10];//column mark
	static int [][] row = new int[9][10];//row mark
	static int [][][] sml = new int[3][3][10];//small matrix mark,每个数字所属于的小色块的标志数组
	static Node [] emp = new Node[81];//empty positions
	static void dfs(int pos) {
		if(pos == cnt) {
			for(int i = 0; i < 9; i++) {
				for(int j = 0; j < 9; j++) {
					System.out.print(map[i][j]);
				}
				System.out.println();
			}
			return;
		}
		int x, y;
		x = emp[pos].x; y = emp[pos].y;
		for(int i = 1; i < 10; i++) {
			if(col[y][i] == 0 && row[x][i] == 0 && sml[x/3][y/3][i] == 0) {
				map[x][y] = i;
				col[y][i] = row[x][i] = sml[x/3][y/3][i] = 1;
				dfs(pos+1);
				col[y][i] = row[x][i] = sml[x/3][y/3][i] = map[x][y] = 0;
			}
		}
	}
	public static void main(String[] args) {
		String s;
		for(int i = 0; i < 9; i++) {
			s = sc.next();
			for(int j = 0; j < 9; j++) {
				map[i][j] = s.charAt(j)-'0';
				if(map[i][j] != 0) {
					col[j][map[i][j]] = 1;
					row[i][map[i][j]] = 1;
					sml[i/3][j/3][map[i][j]] = 1;
				}
				else {
					emp[cnt++] = new Node(i,j);
				}
			}
		}
		dfs(0);
		System.exit(0);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值