#include <iostream>#include <stdio.h>#include <vector>#include <string>#include <fstream>using namespace std;/*问题:Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.The Sudoku board could be partially filled, where empty cells are filled with the character '.'.A partially filled sudoku which is valid.Note:A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.分析:实质就是根据现有数独中已经填充的数字,计算是否有解。数独中每一行和每一列必须包含1~9的数字3*3的数组中必须包含1~9每个数字。此题关键是从何处开始遍历,判断是否能够组成数组:采用每横或每竖列是否每个数字只出现一次,对于每个棋盘判断每个数字是否只出现一次;一旦不符合,重新尝试填新的数字。实际上就是递归来做。关键是填充新的数字必须满足已有条件:1:填充的数字已有出现次数不能超过总数题目中说判断一个数独棋盘是否有效,不需要一定有解,只需要判定该棋盘是否满足其规则采用暴力破解:遍历每一行,每一列分别看每个元素是否出现次数<=1次,输入:9(数独的长度,宽度与之相等)53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79输出:yes关键:1 判断子棋盘是否有效,可以遍历一遍棋盘,每次计算出子棋盘的编号k=i /3 * 3 + j / 3例如(0,5)在第2个棋盘中,对应下标为1for(int i = 0 ; i < size ; i++){ for(int j = 0 ; j < size ; j++ ) { if('.' == board.at(i).at(j)) { continue; } //计算子棋盘编号 subBoard = i / 3 * 3 + j /3 ; num = board[i][j] - '0' - 1;//多减1是因为下标从0开始 if(usedRow[i][num] || usedCol[j][num] || usedSubBoard[subBoard][num]) { return false; } usedRow[i][num] = usedCol[j][num] = usedSubBoard[subBoard][num] = 1; }}*/class Solution{public: bool isValidSudoku(vector<vector<char> > &board) { if(board.empty()) { return false; } int size = board.size(); int usedRow[9][9] = {0}; int usedCol[9][9] = {0}; int usedSubBoard[9][9] = {0}; int subBoard; int num; for(int i = 0 ; i < size ; i++) { for(int j = 0 ; j < size ; j++ ) { if('.' == board.at(i).at(j)) { continue; } //计算子棋盘编号 subBoard = i / 3 * 3 + j /3 ; num = board[i][j] - '0' - 1;//多减1是因为下标从0开始 if(usedRow[i][num] || usedCol[j][num] || usedSubBoard[subBoard][num]) { return false; } usedRow[i][num] = usedCol[j][num] = usedSubBoard[subBoard][num] = 1; } } return true; }};vector<string> readFile(string& fileName){ vector<string> results; if(fileName.empty()) { return results; } ifstream file(fileName , ios::in); if(!file) { cout << "can't open file" << endl; return results; } const int maxSize = 1024; char str[maxSize]; while(!file.eof()) { file.getline(str , maxSize); string s(str); results.push_back(s); } file.close(); return results;}void PRocess(){ vector< vector<char> > board; string s; int size; Solution solution; board.clear(); vector<string> strs = readFile(string("data.txt")); int len = strs.size(); for(int i = 0 ; i < len ; i++) { s = strs.at(i); vector<char> str; size = s.length(); for(int i = 0 ; i < size ; i++) { str.push_back(s.at(i)); } board.push_back(str); } bool result = solution.isValidSudoku(board); if(result) { cout << "yes" << endl; } else { cout << "no" << endl; }}int main(int argc , char* argv[]){ process(); getchar(); return 0;}
新闻热点
疑难解答