程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj(2676)——Sudoku

poj(2676)——Sudoku

編輯:C++入門知識

poj(2676)——Sudoku


 

Description

Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.
\

Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127

哦呵呵,這竟然是一道和實際應用有關的題,是不是做出了這道題然後所有的數獨都是可以被破解的。=。= 醉了

就是一道dfs的題目,然後竟然正搜和反搜時間會差那麼多,額 ,我不知道原因,在此也請高人請教。

首先,我的想法是:肯定是有三種狀態的。

1.是在同一行的數字要不相同,所以我們對在同一行的進行一個數組的存儲

2.是在同一列的數字要不相同,所以我們對在同一列的進行一個數組的存儲

3.是在同一個3*3的格子裡面的要不相同,那麼這裡我們也用一個數組來儲存它們,這裡一開始我卡住了,不知道要怎麼才能存下來,後來也看了網上許多的題解,發現也有點難懂,於是就進行了直接裸的暴力,直接對每個格子for,然後存下來它們已經有的數字就好了。 暴力打法~sad。。。

*這裡唯一要注意的就是在dfs中進行下標的輸出的時候要小心,然後就是在dfs中進行分類討論,首先是當前狀態是0,沒有被填充的時候,那麼就對數字進行枚舉,然後填進去;然後是被填充的時候,那麼就跳過,進行下一個位置的枚舉,注意當如果是當前行的最後一個的時候,那麼要寫成dfs(x+1,0),即為從下一行的第一個位置重新開始枚舉。

 

#include
#include
#include
#include
using namespace std;
#define maxn 11
char a[maxn][maxn];
int row[maxn][maxn],line[maxn][maxn],grid[maxn][maxn];
bool ff=false;
void dfs(int x,int y){
	if(x==-1) {ff=true; return;}
	if(a[x][y]!='0'){
		if(y==0)  dfs(x-1,8);
		else dfs(x,y-1);
		return ;
	}
	else if(a[x][y]=='0'){
		for(int i=1;i<=9;i++){
			if(!line[y][i]&&!row[x][i]&&!grid[x/3*3+y/3][i]){
				a[x][y]=i+'0';
				line[y][i]=1;  row[x][i]=1; grid[x/3*3+y/3][i]=1;
				if(y==0) dfs(x-1,8);
				else dfs(x,y-1);
				if(ff) return ;
				line[y][i]=0; row[x][i]=0; grid[x/3*3+y/3][i]=0;
				a[x][y]='0';
			}
		}
	}
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		memset(row,0,sizeof(row)); memset(line,0,sizeof(line));
		memset(grid,0,sizeof(grid));
		for(int i=0;i<9;i++)  scanf("%s",a[i]);
		//以下是判斷每一行中出現過的數字;  
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++){
				if(a[i][j]-'0'!=0) row[i][a[i][j]-'0']=1;
			}
		}
		//以下是判斷每一列中出現過的數字;
		for(int j=0;j<9;j++){
			for(int i=0;i<9;i++){
				if(a[i][j]-'0'!=0) line[j][a[i][j]-'0']=1;		//j代表是第幾列; 
			}
		} 
		//暴力求格子;
		for(int i=0;i<3;i++)
			for(int j=0;j<3;j++)
			if(a[i][j]-'0'!=0)  grid[0][a[i][j]-'0']=1;
		for(int i=0;i<3;i++)
			for(int j=3;j<6;j++)
			if(a[i][j]-'0'!=0)  grid[1][a[i][j]-'0']=1;	
		for(int i=0;i<3;i++)
			for(int j=6;j<9;j++)
			if(a[i][j]-'0'!=0)  grid[2][a[i][j]-'0']=1; 
		for(int i=3;i<6;i++)
			for(int j=0;j<3;j++)
			if(a[i][j]-'0'!=0)  grid[3][a[i][j]-'0']=1;
		for(int i=3;i<6;i++)
			for(int j=3;j<6;j++)
			if(a[i][j]-'0'!=0)  grid[4][a[i][j]-'0']=1;
		for(int i=3;i<6;i++)
			for(int j=6;j<9;j++)
			if(a[i][j]-'0'!=0)  grid[5][a[i][j]-'0']=1;
		for(int i=6;i<9;i++)
			for(int j=0;j<3;j++)
			if(a[i][j]-'0'!=0)  grid[6][a[i][j]-'0']=1;
		for(int i=6;i<9;i++)
			for(int j=3;j<6;j++)
			if(a[i][j]-'0'!=0)  grid[7][a[i][j]-'0']=1;
		for(int i=6;i<9;i++)
			for(int j=6;j<9;j++)
			if(a[i][j]-'0'!=0)  grid[8][a[i][j]-'0']=1;
		ff=false;
		dfs(8,8);
		for(int i=0;i<9;i++){
			printf("%s\n",a[i]);
		}
	}
}


 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved