【ybtoj 高效進階 1.4】【深搜】數獨遊戲

ssl_yty發表於2021-01-03

【ybtoj 高效進階 1.4】【深搜】數獨遊戲

題目

在這裡插入圖片描述


解題思路

用字串輸入
將其轉換成數值放入陣列a
陣列l統計當前行數字的使用情況
陣列r統計當前列數字的使用情況
陣列f統計當前3*3方格數字的使用情況
列舉當前格可以填的數字


程式碼

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[10][10],l[10][10],r[10][10],f[5][5][10],p;
string s;
int k(int x)
{
	if (x<4) return 1;
	if (x<7) return 2;
	return 3;
}
void dfs(int x,int y)
{ 
	 if (p) return;  //已經輸出答案
	 if (x>9)  //
	 {
	 	for (int i=1;i<=9;i++)
	 	    for (int j=1;j<=9;j++)
	 	        printf("%d",a[i][j]);
	 	printf("\n");
	 	p=1;
	 	return;
	 }
	 if (a[x][y])
	 	if (y==9)
	 	   dfs(x+1,1);
	 	   else dfs(x,y+1);
	 for (int i=1;i<=9;i++)
	     if (!l[x][i]&&!r[y][i]&&!f[k(x)][k(y)][i]&&a[x][y]==0)  //判斷是否能填
	     {
	     	a[x][y]=i;
	     	l[x][i]=r[y][i]=f[k(x)][k(y)][i]=1;
	     	if (y==9)
	 	       dfs(x+1,1);
	 	       else dfs(x,y+1);
	 	    l[x][i]=r[y][i]=f[k(x)][k(y)][i]=0;
	 	    a[x][y]=0;  //回溯
		 }
}
int main()
{
	while (cin>>s)
	{ 
		  if(s=="end")
		  	return 0;
	      p=0;
		  memset(l,0,sizeof(l));
		  memset(r,0,sizeof(r));
		  memset(f,0,sizeof(f));  //清0
		  for (int i=1;i<=9;i++)
		      for (int j=1;j<=9;j++)
		          if (s[(i-1)*9+j-1]!='.')
				  {
				     a[i][j]=s[(i-1)*9+j-1]-48;
		      	     l[i][a[i][j]]=1;
		      	     r[j][a[i][j]]=1;
		      	     f[k(i)][k(j)][a[i][j]]=1;  
			      }
		          else a[i][j]=0;  //預處理
		  dfs(1,1);         
	}
	return 0;
}

相關文章