poj2676(数独 搜索)
题意
解出N个9x9的数独,(输出一个解即可)
解题思路
用一个二维布尔数组来标记,点(x,y)的行,列,块的数字是否已经出现过,然后直接暴力搜索即可
AC代码
#include<vector>
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<set>
#include<cstring>
#include<functional>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,pii> PII;
bool vis[100][10];
int G[10][10];
int N = 10;
int M = 20;
inline int getid(int& x,int& y) //得到(x,y)所属的块
{
if(x<3&&y<3) return M+1;
else if(x<6&&y<3) return M+2;
else if(x<9&&y<3)return M+3;
else if(x<3&&y<6)return M+4;
else if(x<6&&y<6) return M+5;
else if(x<9&&y<6) return M+6;
else if(x<3&&y<9)return M+7;
else if(x<6&&y<9) return M+8;
else return M+9;
}
bool ojbk = 0;
void dfs(int x,int y)
{
if(ojbk)return;
if(y>8){
y %= 9;
x++;
}
if(x==9&&y==0){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
cout << G[i][j];
}
}
ojbk = 1;
}
if(G[x][y]){
dfs(x,y+1);
return;
}
int r = y;
int c = N+x;
int id = getid(x,y);
for(int k=1;k<=9;k++){
if(vis[r][k]||vis[c][k]||vis[id][k]) continue;
G[x][y] = k;
vis[r][k] = 1;
vis[c][k] = 1;
vis[id][k] = 1;
dfs(x,y+1);
G[x][y] = 0; //回朔
vis[r][k] = 0;
vis[c][k] = 0;
vis[id][k] = 0;
}
}
int main(int argc, char const *argv[])
{
string s;
while(cin >> s){
if(s=="end")break;
ojbk = 0;
memset(vis,0,sizeof(vis));
int k = 0;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(s[k]=='.'){
G[i][j] = 0;
k++;
continue;
}
G[i][j] = s[k++]-'0';
if(G[i][j]==0)continue;
vis[j][G[i][j]] = 1;
vis[N+i][G[i][j]] = 1;
vis[getid(i,j)][G[i][j]] = 1;
}
}
dfs(0,0);
cout << endl;
}
return 0;
}