In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
. | 2 | 7 | 3 | 8 | . | . | 1 | . |
. | 1 | . | . | . | 6 | 7 | 3 | 5 |
. | . | . | . | . | . | . | 2 | 9 |
3 | . | 5 | 6 | 9 | 2 | . | 8 | . |
. | . | . | . | . | . | . | . | . |
. | 6 | . | 1 | 7 | 4 | 5 | . | 3 |
6 | 4 | . | . | . | . | . | . | . |
9 | 5 | 1 | 8 | . | . | . | 7 | . |
. | 8 | . | . | 6 | 5 | 3 | 4 | . |
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
Input
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
Output
For each test case, print a line representing the completed Sudoku puzzle.
Sample Input
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end
Sample Output
527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936
数独问题,暴搜;
有一个优化,优先搜索可填位置少的;
同时一个位置一个位置填,一次一个位置就好;
可以用二进制储存状态;
其中我给出自己写的超时代码如下:(问题还是无法解决)TT_TT!!!
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//考虑为bool类型也可以实现
int row[10][10];//判断row[i][x],在i行x是否出现(bool)
int col[10][10];//判断 col[j][y],在j列y是否出现(bool)
int map[10][10];//处理输入
int small[10][10];//处理3*3格子(bool)
bool flag=false;
int f(int x,int y){
return 3*((x-1)/3)+(y-1)/3+1;//返回x,y出现在哪个具体的网格
}
void input(){
char ch;
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
scanf("%c",&ch);
if(ch=='.')
map[i][j]=0;//处理为0元素
else
map[i][j]=ch-'0';
if(map[1][1]=='e'-'0'&&map[1][2]=='n'-'0'&&map[1][2]=='d'-'0'){
flag=true;
return;
}
}
}
}
void init(){
int i,j;
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
memset(small,0,sizeof(small));
for(i=1;i<=9;i++){
for(j=1;j<=9;j++){
if(map[i][j]){//不处理0的情况
int k;
k=f(i,j);
row[i][map[i][j]]=1;//在i行出现map[i][j];
col[j][map[i][j]]=1;//在j列出现map[i][j];
small[k][map[i][j]]=1;//map[i][j]属于第k个网格
}
}
}
}
int dfs(int x,int y){
if(x==10)
return 1;
int flag=0;
if(map[x][y]){
if(y==9)
flag=dfs(x+1,1);
else
flag=dfs(x,y+1);
if(flag)
return 1;
else
return 0;
}
else{
int k=f(x,y);
for(int i=1;i<=9;i++)
if(!row[x][i]&&!col[y][i]&&!small[k][i]){
map[x][y]=i;
row[x][i]=1;
col[y][i]=1;
small[k][i]=1;
if(y==9)
flag=dfs(x+1,1);
else
flag=dfs(x,y+1);
if(!flag){
map[x][y]=0;
row[x][i]=0;
col[y][i]=0;
small[k][i]=0;
}
else
return 1;
}
}
return 0;
}
int main(){
while(1){
input();
if(flag)
break;
else{
init();
getchar();//用于缓冲,不能或缺
dfs(1,1);
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
cout<<map[i][j];
cout<<endl;
}
}
return 0;
/***string s;
cin>>s;
cout<<s.size()<<endl;//输出的结果是81.
***/
}
AC代码如下
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 15;
int r[MAXN], c[MAXN], k[MAXN];
int lg[1 << 10], num[1 << 10];
char s[MAXN * MAXN], a[MAXN][MAXN];
inline int ID(int i, int j){
return 3 * (i / 3) + j / 3;
}
inline void draw(int x, int y, int z){
r[x] ^= 1 << z;
c[y] ^= 1 << z;
k[ID(x, y)] ^= 1 << z;
}
bool dfs(int cnt){
if(cnt == 81) return true;
int x, y, mint = 10;
REP(i, 0, 9)
REP(j, 0, 9)
if(a[i][j] == '.'){
int val = num[r[i] & c[j] & k[ID(i, j)]];
if(!val) return false;
if(mint > val){
mint = val;
x = i, y = j;
}
}
int tmp = r[x] & c[y] & k[ID(x, y)];
for(; tmp; tmp -= tmp & (-tmp)){
int t = lg[tmp & (-tmp)];
a[x][y] = t + '1';
draw(x, y, t);
if(dfs(cnt + 1)) return true;
draw(x, y, t);
a[x][y] = '.';
}
return false;
}
int main(){
REP(i, 0, 9) lg[1 << i] = i;
REP(i, 0, 1 << 9)
for(int j = i; j; j -= j & (-j)) num[i]++;
while(scanf("%s", s) && s[0] != 'e'){
int cnt = 0;
REP(i, 0, 9) c[i] = r[i] = k[i] = (1 << 9) - 1;
REP(i, 0, 9)
REP(j, 0, 9){
a[i][j] = s[i * 9 + j];
if(a[i][j] != '.') cnt++, draw(i, j, a[i][j] - '1');
}
dfs(cnt);
REP(i, 0, 9)
REP(j, 0, 9)
s[i * 9 + j] = a[i][j];
puts(s);
}
}