数独,解题

package acm;

import java.util.Scanner;

/**
 * http://acm.nyist.net/JudgeOnline/problem.php?pid=722
 * @author yes.yuan
 * sample_input
1
8 0 0 0 0 0 0 0 0
0 0 3 6 0 0 0 0 0
0 7 0 0 9 0 2 0 0
0 5 0 0 0 7 0 0 0
0 0 0 0 4 5 7 0 0
0 0 0 1 0 0 0 3 0
0 0 1 0 0 0 0 6 8
0 0 8 5 0 0 0 1 0
0 9 0 0 0 0 4 0 0

result
8 1 2 7 5 3 6 4 9 
9 4 3 6 8 2 1 7 5 
6 7 5 4 9 1 2 8 3 
1 5 4 2 3 7 8 9 6 
3 6 9 8 4 5 7 2 1 
2 8 7 1 6 9 5 3 4 
5 2 1 9 7 4 3 6 8 
4 3 8 5 2 6 9 1 7 
7 9 6 3 1 8 4 5 2 

 */


public class acm722 {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        long time = System.currentTimeMillis();
        for (int tc = 0; tc < t; tc++) {
            map = new int[size][size];
            data = new int[9*9][2];
            nums = new int[9*9][10];
            len = 0;
            for (int x = 0; x < size; x++)
                for (int y = 0; y < size; y++) {
                    map[x][y] = sc.nextInt();
                    if(map[x][y] == 0) {
                        data[len][0] = x;
                        data[len][1] = y;
                        len++;
                    }
                }
            for (int i = 0; i < len; i++) {
                int x = data[i][0];
                int y = data[i][1];
                nums[i] = nums( x, y);
            }
            if(dfs(0, 0)){
                for (int i = 0; i < size; i++) {
                    for (int j = 0; j < size; j++) {
                        System.out.print(map[i][j] +" ");
                    }
                    System.out.println();
                }
            }
        }
        System.out.println("time="+(System.currentTimeMillis()-time));
    }
    static int  size = 9,map[][], data[][], nums[][], len;
    static boolean dfs(int step1,int step2){
        int x = data[step1][0],y = data[step1][1];
        if(step1==len)  return true;
        for (int i = step2; nums[step1][i]!=-1; i++) {
            map[x][y] = nums[step1][i];
            if(inrangrhor(x,y)&&inrangrver(x,y)&&inrangrblock(x, y)) {
                if(dfs(step1+1,0)) {
                    return true;
                }
            }
            map[x][y] = 0;
        }
        return false;
    }
    static boolean inrangrhor(int x,int ty){
        int key = map[x][ty];
        for (int y = 0; y < size; y++) {
            if(y!=ty&&map[x][y]!=0){
                if(key==map[x][y]) {
                    return false;
                }
            }
        }
        return true;
    }
    static boolean inrangrver(int tx,int y){
        int key = map[tx][y];
        for (int x = 0; x < size; x++) {
            if(x!=tx&&map[x][y]!=0){
                if(key==map[x][y]) {
                    return false;
                }
            }
        }
        return true;
    }
    static boolean inrangrblock(int tx,int ty){
        int key = map[tx][ty];
        int x = tx/3;
        int y = ty/3;
        for (int i = x*3; i < x*3+3; i++) 
            for (int j = y*3; j < y*3+3; j++) {
                if(i!=tx&&j!=ty&&map[i][j]!=0){
                    if(key==map[i][j]) {
                        return false;
                    }
                }
            }
        return true;
    }
    static int[] nums(int tx,int ty){
        int d[] = new int[10];
        for (int y = 0; y < size; y++)
            if(map[tx][y]!=0){
                d[map[tx][y]] = 1;
            }
        for (int x = 0; x < size; x++) 
            if(map[x][ty]!=0){
                d[map[x][ty]] = 1;
            }
        int x = tx/3;
        int y = ty/3;
        for (int i = x*3; i < x*3+3; i++)
            for (int j = y*3; j < y*3+3; j++)
                if(map[x][ty]!=0) {
                    d[map[x][ty]] = 1;
                }
        int result[] = new int[10],cnt = 0;
        for (int i = 1; i < d.length; i++)
            if(d[i]==0){
                result[cnt++] = i;
            }
        result[cnt++] = -1;
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值