标签:spec ext plm 0ms with 这一 exactly ons ros
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 24081 | Accepted: 11242 | Special Judge |
Description
Input
Output
Sample Input
1 103000509 002109400 000704000 300502006 060000050 700803004 000401000 009205800 804000107
Sample Output
143628579 572139468 986754231 391542786 468917352 725863914 237481695 619275843 854396127
题意:就是普通的数独游戏,给出了初始状态的九宫格,让你打印出任意一种解法。
思路:这题用DFS来写。我们运用三个数组进行标记,从而得知每个格子可以放那些数,不可以放哪些数,然后dfs枚举即可。三个标记数组分别为line[][],column[][],block[][],
line:标记每一行哪些数已经被用了,哪些没被用;
column:标记每一列哪些数已经被用了,哪些没被用;
block:标记每一个3*3格子中哪些数被用过,哪些没被用;(判断某个格子为第几个块:3*3的块总共有三行和三列,假设格子索引从1-9,某个格子为第i行,第j列,可以知道它是(i-1)/3行的块,而且是(j-1)/3+1列的列,所以可以知道某个格子为第(i-1)/3*3+(j-1)/3+1块)
然后从第一个需要填数的格子开始,枚举1-9中可以填的所有数,然后将选中的数标记,继续下一个格子,若到达某个格子无数可选,则回溯。
具体看代码,最近在学Java,所以代码是用java写的,但语法基本和C++相同,所以不会java也能看懂。
代码:
1 import java.util.Scanner; 2 3 public class Main { 4 static boolean line[][]; //标记行的数组,一维的数字表示第几行,二维的数字表示这一行的哪一个数 5 static boolean column[][]; //标记列的数组 6 static boolean block[][]; //标记块的数组 7 8 public static void main(String[] args) { 9 Scanner in = new Scanner(System.in); 10 int t = in.nextInt(); //输入t 11 while(t-- > 0) 12 { 13 line = new boolean[15][15]; //数组初始化 14 column = new boolean[15][15]; 15 block = new boolean[15][15]; 16 17 int map[][] = new int[15][15]; 18 int all = 0; //all用来统计有多少个格子需要填数 19 for(int i=1; i<10; ++i) { 20 String s = in.next(); //输入字符串 21 22 for(int j=1; j<10; ++j) { 23 map[i][j] = s.charAt(j-1) - ‘0‘; //将字符串转化为数字存入数组 24 if(map[i][j] == 0) all++; //统计 25 26 line[i][ map[i][j] ] = true; //标记每一个已经出现的数 27 column[j][ map[i][j] ] = true; 28 int xx = (i-1)/3*3 + (j-1)/3 + 1; //计算这个格子在第几个3*3的块中 29 block[xx][ map[i][j] ] = true; 30 } 31 } 32 33 outer:for(int i=1; i<10; ++i) //找到第一个需要填的格子 34 for(int j=1; j<10; ++j) { 35 if(map[i][j] == 0) 36 { 37 DFS(i,j,all,map); 38 break outer; //跳出到循环外 39 } 40 } 41 42 for(int i=1; i<10; ++i) 43 { 44 for(int j=1; j<10; ++j) 45 { 46 System.out.print(map[i][j]); 47 } 48 System.out.println(); 49 } 50 } 51 in.close(); 52 } 53 54 static boolean DFS(int x,int y,int all,int[][] map) { 55 56 if(all == 0) { //如果所有的格子都被填满,返回true 57 return true; 58 } 59 60 int x1=0,y1=0; 61 outer:for(int i=x; i<10; ++i) //找到这个格子之后需要填数的第一个格子 62 for(int j=1; j<10; ++j) 63 { 64 if(i==x && j==y) continue; //跳过目前这个格子 65 if(map[i][j] == 0) 66 { 67 x1 = i; 68 y1 = j; 69 break outer; 70 } 71 } 72 73 int xx = (x-1)/3*3 + (y-1)/3 + 1; //计算这个格子为第几个块 74 for(int k=1; k<10; ++k) { 75 if(!line[x][k] && !column[y][k] && !block[xx][k] ) //若这个数未被标记,表示可选 76 { 77 map[x][y] = k; //在这个格子存储这个数 78 line[x][k] = true; //将这个数标记 79 column[y][k] = true; 80 block[xx][k] = true; 81 82 if(DFS(x1,y1,all-1,map)) //搜索下一个需要填数的格子 83 return true; 84 85 line[x][k] = false; //能运行到这里,说明填数失败,所以回溯 86 column[y][k] = false; 87 block[xx][k] = false; 88 } 89 } 90 map[x][y] = 0; //若没有一个数满足要求,则回到上一个数,且要把这个数变回0; 91 return false; 92 } 93 }
标签:spec ext plm 0ms with 这一 exactly ons ros
原文地址:https://www.cnblogs.com/tuyang1129/p/9614177.html