36.有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
#include<iostream>
using namespace std;
char arr[9][9];
bool vis_hang[10][10]; //每一行的1-9有没有使用
bool vis_lie[10][10]; //每一列的1-9有没有使用
bool vis_ge[10][10]; //每个小个子的1-9有没有使用
void _print(){
for(int a = 0; a < 9; a++){
for(int b = 0; b < 9; b++){
if(b == 8)
cout<<arr[a][b]<<endl;
else
cout<<arr[a][b]<<" ";
}
}
}
bool f;
void dfs(int x ,int y){
if(f){
return;
}
if(x == 9){
f = true;
_print();
return;
}
if(y == 9){
dfs(x + 1,0);
}
if(arr[x][y] != '*'){
dfs(x, y + 1);
return;
}
for(int a = 1; a <= 9; a++){
if(!vis_hang[x][a] && !vis_lie[y][a] && !vis_ge[x / 3 * 3 + y / 3][a]){
vis_hang[x][a] = true;
vis_lie[y][a] = true;
vis_ge[x / 3 * 3 + y / 3 ][a] =true;
arr[x][y] = a + '0';
dfs(x, y+1);
vis_hang[x][a] = false;
vis_lie[y][a] = false;
vis_ge[x / 3 * 3 + y / 3 ][a] = false;
arr[x][y] = '*';
}
}
}
int main()
{
for(int a = 0; a < 9; a++){
for(int b = 0; b < 9; b++){
cin>>arr[a][b];
}
}
for(int a = 0; a < 9; a++){
for(int b = 0; b < 9; b++){
if(arr[a][b] != '*'){
vis_hang[a][arr[a][b] - '0'] = true;
vis_lie[b][arr[a][b] - '0'] = true;
vis_ge[a / 3 * 3 + b / 3][arr[a][b] - '0'] = true;
}
}
}
dfs(0,0);
return 0;
}
解答:这是填充数独的代码 ,由于我曾经写过这个代码就一股脑的回溯然后判断是否可以填充完毕再判断是否有效。确实是费时费力,不可取。
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
int xsp[9][9] = {0};
int ysp[9][9] = {0};
int lsp[9][9] = {0};
for(int i = 0; i < 9; i++)
{
for(int j = 0; j < 9; j++)
{
if(board[i][j] != '.')
{
if(( ++xsp[board[i][j]-'1'][i] > 1) ||
(++ysp[board[i][j]-'1'][j] >1) ||
(++lsp[board[i][j]-'1'][(i/3)*3 + j/3] >1))
{
return false;
}
}
}
}
return true;
}
};
解答:根据题目给的思路只要这样写就可以了 判断每个数在每一行每一列每一个小方块只出现一次就行,至于小方块哪里为啥事i/3*3 + j/3 数独里有介绍。
认真看清题目,就能少碰壁