【转载请注明】http://www.cnblogs.com/igoslly/p/8719622.html
来看一下题目:
Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character You may assume that there will be only one unique solution. |
题目意思: 完成数独游戏的计算 |
在做这题的前两天,楼主正在摸索华为笔试题的时候,已经写了一个非常直白的实现,具体链接如下:
http://www.cnblogs.com/igoslly/p/8708960.html
不过和原题有些区别:① 所有数据均以字符串形式保存 ② 需要填写的位置以 “.” 代替 0
我们稍稍修改下代码,就可以得到实现方法1:
bool check(int n,char key,vector<vector<char>> num){
for(int i=;i<;i++){
int j=n/;
if(num[j][i]==key)
{
return false;
}
}
for(int i=;i<;i++)
{
int j=n%;
if(num[i][j]==key){return false;}
} int x=n//*;
int y=n%/*;
for(int i=x;i<x+;i++){
for(int j=y;j<y+;j++){
if(num[i][j]==key){return false;}
}
}
return true;
}
void dfs(int n,vector<vector<char>> &num,bool *sign){
if(n>)
{
*sign=true;
return;
}
if(num[n/][n%]!='.')
{
dfs(n+,num,sign);
}else{
for(char i='';i<='';i++)
{
if(check(n,i,num)==true){
num[n/][n%]=i;
dfs(n+,num,sign);
if(*sign==true) return;
}
}
num[n/][n%]='.';
}
}
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
bool sign=false;
dfs(,board,&sign);
}
};
实现方法2:
优化check函数,将原先逐行、逐列遍历进行判断的方法 → 记录每行、每列、每九宫格是否含有当前数字
具体实施(较原先冗长的代码简短太多):
// line[i][j],column[i][j],subcube[i][j] 分别代表数独每行、每列、每个子单元是否含有数字j(对应1-9)
bool line[][],column[][],subcube[][];
进行dfs前,首先要对原题给出的数字进行记录
// 将所有数组置为false
memset(line,false,sizeof(line));
memset(column,false,sizeof(column));
memset(subcube,false,sizeof(subcube));
// 根据题意,设定初始数组的值
for(int i=;i<;i++){
for(int j=;j<;j++){
if(board[i][j]=='.')
continue; int num=board[i][j]-'';
// 给定题目存在问题,无解,直接返回
int cube=i/* + j/;
if(line[i][num] || column[j][num] || subcube[cube][num])
return ;
line[i][num] = column[j][num] = subcube[cube][num] = true;
}
}
实现方法3:
在实现方法1中,我们使用 n = 0~80 来记录当前填充空格,根据 n 是否越界判断数独填充是否完成。
当然我们也可以采用 i & j / row & col 对位置进行记录,更为直观;
逐行进行填充时,需要对 j > 8 (初始 0)进行换行操作:
// 当j>8时,i++,否则 i 值不变
// 当j>8时,及时取余,重新从0~8计算
(i,j) -> (i+(j+)/,(j+)%)
具体递归代码:
bool step(vector<vector<char>>&board,int i,int j){
if(i==)
return true;
if(board[i][j]!='.')
{
if(i==&&j==){
return true;
}
else{
return step(board,i+(j+)/,(j+)%); // step里值表示i,j换行
}
} int cube=i/* + j/;
for(int k=;k<;k++){
if(line[i][k] || column[j][k] || subcube[cube][k])
continue;
line[i][k] = column[j][k] = subcube[cube][k] = true;
board[i][j] = ''+k; if(step(board,i+(j+)/,(j+)%)) // 若数独已完成,直接返回true
return true;
line[i][k] = column[j][k] = subcube[cube][k] = false;
board[i][j] = '.';
}
return false;
}
G
M
T
Detect language Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bengali Bosnian Bulgarian Catalan Cebuano Chichewa Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hausa Hebrew Hindi Hmong Hungarian Icelandic Igbo Indonesian Irish Italian Japanese Javanese Kannada Kazakh Khmer Korean Lao Latin Latvian Lithuanian Macedonian Malagasy Malay Malayalam Maltese Maori Marathi *n Myanmar (Burmese) Nepali Norwegian Persian Polish Portuguese Punjabi Romanian Russian Serbian Sesotho Sinhala Slovak Slovenian Somali Spanish Sundanese Swahili Swedish Tajik Tamil Telugu Thai Turkish Ukrainian Urdu Uzbek Vietnamese Welsh Yiddish Yoruba Zulu |
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bengali Bosnian Bulgarian Catalan Cebuano Chichewa Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hausa Hebrew Hindi Hmong Hungarian Icelandic Igbo Indonesian Irish Italian Japanese Javanese Kannada Kazakh Khmer Korean Lao Latin Latvian Lithuanian Macedonian Malagasy Malay Malayalam Maltese Maori Marathi *n Myanmar (Burmese) Nepali Norwegian Persian Polish Portuguese Punjabi Romanian Russian Serbian Sesotho Sinhala Slovak Slovenian Somali Spanish Sundanese Swahili Swedish Tajik Tamil Telugu Thai Turkish Ukrainian Urdu Uzbek Vietnamese Welsh Yiddish Yoruba Zulu |
Text-to-speech function is limited to 200 characters