数独
描述 数独是一个非常简单的任务。一个9行9列的正方形表被分成9个较小的3x3,如图所示。在一些单元格中,从1写到9的十进制数字。其他细胞是空的。目标是用从1到9的十进制数字填充空单元格,每个单元格有一个数字,这样在每一行、每列和每个标记为3x3的子方格中,将出现从1到9的所有数字。编写一个程序来解决给定的数独任务.
输入 输入数据将从测试用例的数量开始。对于每个测试用例,后面有9行,对应于表的行。在每一行上都会给出一个精确的9位小数字符串,对应于这一行中的单元格。如果单元格为空,则由0表示。
输出量 对于每个测试用例,您的程序应该以与输入数据相同的格式打印解决方案。空的单元格必须按照规则填充。如果解决方案不是唯一的,那么程序可以打印其中的任何一个。
样本输入 1 103000509 002109400 000704000 300502006 060000050 700803004 000401000 009205800 804000107 样本输出 143628579 572139468 986754231 391542786 468917352 725863914 237481695 619275843 854396127 来源 |
大致题意和思路:
题目中的部分点是固定的,需要在第一遍读入中处理完;接着进行依次深度优先搜索,每枚举一位,要判断是否与当前行冲突或者当前列冲突,或者是否当前所在的小格子里的冲突了;如果都没有那么当前状态就达到了“稳定”,接着迭代搜索下一位,直到完成即可!
搜索的时候,会遇见三种情况,上面是第一种,第二种是遇见固定的直接跳到下一位,如果下一位(x,y)的y是10的话,就可以达到巧妙换行的要求了。
题解:
#include<stdio.h> #include<iostream> #include<string.h> #include<vector> #include<math.h> #include<stdlib.h> #include<algorithm> #include<set> #include<string.h> #include<string> #include<map> #include<queue> using namespace std; #define ll long long #define ull unsigned long long #define inf 0x3f3f3f3f int a[10][10];//从(1,1)一直存到(9,9) bool vis[10][10]; bool Fixed[10][10];//当前位置是否可以已经固定了! bool grid[10][10];//1--9的大方格的1--9的使用了1/0次 bool row[10][10];//横行 bool col[10][10];//列 int flag; int getnum(int i,int j){//返回(i,j)所在的小九宫格的序号 if(i>=1&&i<=3&&j>=1&&j<=3)return 1; if(i>=1&&i<=3&&j>=4&&j<=6)return 2; if(i>=1&&i<=3&&j>=7&&j<=9)return 3; if(i>=4&&i<=6&&j>=1&&j<=3)return 4; if(i>=4&&i<=6&&j>=4&&j<=6)return 5; if(i>=4&&i<=6&&j>=7&&j<=9)return 6; if(i>=7&&i<=9&&j>=1&&j<=3)return 7; if(i>=7&&i<=9&&j>=4&&j<=6)return 8; if(i>=7&&i<=9&&j>=7&&j<=9)return 9; } void init(){ memset(Fixed,false,sizeof(Fixed)); memset(a,0,sizeof(a)); memset(vis,false,sizeof(false)); memset(grid,false,sizeof(grid)); flag=0; memset(row,false,sizeof(row)); memset(col,false,sizeof(col)); } void dfs(int i,int j){ if(flag==1)return ; if(i==9&&j==10){ for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ printf("%d",a[i][j]); } cout<<endl; } flag=1; return ; } if(j==10) dfs(i+1,1); else if(Fixed[i][j]==true) dfs(i,j+1); else{ int num; for(num=1;num<=9;num++){ if(flag==1)return ; if(grid[getnum(i,j)][num]==true)continue; if(row[i][num]==true)continue; if(col[j][num]==true)continue; a[i][j]=num;//记录结果!! grid[getnum(i,j)][num]=true; row[i][num]=true;col[j][num]=true; dfs(i,j+1); row[i][num]=false;col[j][num]=false; grid[getnum(i,j)][num]=false; } } } int main(){ int T; scanf("%d",&T); while(T--){ init(); int x; for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ scanf("%1d",&x); if(x!=0){ a[i][j]=x; Fixed[i][j]=true; grid[getnum(i,j)][x]=1; row[i][x]=1; col[j][x]=1; } } } dfs(1,1); } return 0; }