问题描述
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
上图是一个部分填充的有效的数独。
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
说明:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
给定数独序列只包含数字 1-9 和字符 ‘.’ 。
给定数独永远是 9x9 形式的
输入说明
输入9行,每行9个字符,只包含数字 1-9 和字符 ‘.’
83..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
输出说明
false
代码思路
在遍历时分别用三个矩阵来记录每一行、每一列、每一个块中数字1-9是否出现,若当前字符在同一行、列或块中没有出现过,则将行、列、块中对应的位置符之为1,继续下一个数字的循环;若当前字符在同一行、列或者块中已经出现过,则返回false,退出循环。
关键的问题是如何表示出每个字符所在的块,(没有想到,借【chao】鉴【xi】了大佬的思路),表达式为box_index = (row / 3) * 3 + columns / 3
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board){
int row[9][10]={0};
int col[9][10]={0};
int box[9][10]={0};
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.')
continue;
int curNum=board[i][j]-'0';
if(row[i][curNum])
return false;
if(col[j][curNum])
return false;
if(box[3*(i/3)+j/3][curNum])
return false;
row[i][curNum]=1;
col[j][curNum]=1;
box[3*(i/3)+j/3][curNum]=1;
}
}
return true;
}
};
int main()
{
vector<vector<char> > board;
char ch;
for(int i=0; i<9; i++)
{
vector<char> aLine;
for(int j=0; j<9; j++)
{
cin>>ch;
aLine.push_back(ch);
}
board.push_back(aLine);
}
bool res=Solution().isValidSudoku(board);
cout<<(res?"true":"false")<<endl;
return 0;
}