牛客-數獨挑戰(dfs)

數獨遊戲
題目鏈接
1 暴力法(TLE)


#include<bits/stdc++.h>
using namespace std;
const int inf= 0x3f3f3f3f;
typedef long long ll;
int e[10][10];
int r[10][10];   //記錄該行 1-9是否出現 出現爲 1
int c[10][10];
int k[10][10][10]; 
struct node{
    int x, y;
}cal[100];
int ck(int i,int j) //判斷i,j是否有滿足條件的答案
{
    int tans;
    vector<int>tmp;
    for(int m=1;m<=9;m++)
    {
        if(r[i][m]==c[j][m]&&c[j][m]==k[(i-1)/3][(j-1)/3][m]
        &&k[(i-1)/3][(j-1)/3][m]==0)
        {
            tmp.push_back(m);
        }
             
    }
    if(tmp.size()==1) tans = tmp.back();
    else tans = 0;
    return tans;
}
void prin()
{
	for(int i1=1;i1<=9;i1++)
    {
        for(int j1=1;j1<=9;j1++)
        printf("%d ",e[i1][j1]);
        printf("\n");
    }
}
int main()
{
    int cn=0,cnt=0;
    for(int i=1;i<=9;i++) for(int j=1;j<=9;j++)
    {
        cin>>e[i][j];
        r[i][e[i][j]]=1;          //在這行 e[i][j]這個數出現了
        c[j][e[i][j]]=1;          //在這列 e[i][j]這個數出現了
        k[(i-1)/3][(j-1)/3][e[i][j]]=1;  //在這塊 出現了
        if(e[i][j]==0)
        {
            cal[cn].x=i;
            cal[cn].y=j;
            cn++;
        }
    }             //cn個需要處理的數
    while(1)
    {
        for(int p=0;p<cn;p++)
        {
            int i = cal[p].x;
            int j = cal[p].y;
            if(e[i][j]) continue;
            int tt = ck(i,j);
            if(tt)
            {
                e[i][j] = tt;
                r[i][tt]=c[j][tt]=k[(i-1)/3][(j-1)/3][tt]=1;
                cnt++;
                if(cnt==cn)
                {
                    prin();
                    return 0;
                }
            }
        }
    }
     
}

2 回溯法

#include<bits/stdc++.h>
using namespace std;
const int inf= 0x3f3f3f3f;
typedef long long ll;
int e[10][10]; 
int r[10][10];   //記錄該行 1-9是否出現 出現爲 1 
int c[10][10];
int k[3][3][10];  
struct node{
	int x, y;
}cal[100];
int cn;
int flag=0;
void dfs(int s)  
{
	if(flag) return ;
	if(s==cn)
	{
		flag=1;
		for(int i1=0;i1<9;i1++)
		{
			for(int j1=0;j1<9;j1++)
			printf("%d ",e[i1][j1]);
			printf("\n");
		}
	}
	for(int m=1;m<=9;m++)
	{
		int i = cal[s].x;
		int j = cal[s].y;
		if(!r[i][m]&&!c[j][m]&&!k[i/3][j/3][m])
		{
			r[i][m] = c[j][m] = k[i/3][j/3][m]=1;
			e[i][j] = m;
			dfs(s+1);
			r[i][m] = c[j][m] = k[i/3][j/3][m]=0;
			e[i][j] = 0;
		}
	}
}
int main()
{
	
	for(int i=0;i<9;i++) for(int j=0;j<9;j++)
	{
		cin>>e[i][j];
		r[i][e[i][j]]=1;          //在這行 e[i][j]這個數出現了
		c[j][e[i][j]]=1;          //在這列 e[i][j]這個數出現了
		k[i/3][j/3][e[i][j]]=1;  //在這塊 出現了 
		if(e[i][j]==0)
		{
			cal[cn].x=i; 
			cal[cn].y=j;
			cn++;
		}
	}            
	dfs(0);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章