+カット枝DFSを解決するための数独のC ++

  ブラシHuawei社のコンピュータ・検査(ポータル:数独)、数独に関するトピックへのブラシ、数独は、彼がデータの83%にわたり削減枝のDFSを書いたことをどのような特別なソリューションと思ったが、多くの学生私が私というふりをして、話題の問題、この問題のいくつかの解決策が、別のアプローチは、異なる答えがありますが、答えが正しい、そして非常にイライラでのみテストがあると推定され、同じ問題を抱えていますそれは今です。

以前は一人でGuoshuoを聞いたが、数独についての知識のビットを学習することにより深さ、ブラシタイトル今日では研究されていない、効率的などのような解決策を考えることができない、DFS +枝カットを書いて、実際に結果を捨てることができ、信じられませんコードそれを見て具体的なアイデアは、非常に迅速な感じまで実行されています:

#include<bits/stdc++.h>
#include<hash_set>
#define ll long long
#define qq printf("QAQ\n");
#define setit set<int>::iterator
using namespace std;
const int maxn=1e5+5;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
int mp[10][10];
bool visrow[10][10],viscol[10][10],vispla[10][10],flag;
/*     visrow 行标记 i行1-9那些数已经出现过了
        viscol 列标记 vislpa宫标记
*/
void dfs(int pos)//pos表示当前位置
{
    //printf("pos=%d\n",pos);
    if(flag)return ;//已经找到正确答案了(注释可以得到全部答案)
    if(pos==81){//到达出口
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
            printf("%d%c",mp[i][j],j==9?'\n':' ');
        flag=1;
    }
    int x=pos/9+1,y=pos%9+1;//根据pos计算行类坐标
    int pla=((x-1)/3)*3+(y-1)/3+1;//计算宫编号
    if(mp[x][y])dfs(pos+1);
    else {
        for(int i=1;i<=9;i++)
        {
            if(visrow[x][i]||viscol[y][i]||vispla[pla][i])continue;//行列宫已经出现过这个数了
            visrow[x][i]=1;
            viscol[y][i]=1;
            vispla[pla][i]=1;

            mp[x][y]=i;
            dfs(pos+1);//dfs 枚举操作
            mp[x][y]=0;

            visrow[x][i]=0;
            viscol[y][i]=0;
            vispla[pla][i]=0;
        }
    }
}
int main()
{
    memset(visrow,0,sizeof visrow);
    memset(viscol,0,sizeof viscol);
    memset(vispla,0,sizeof vispla);
    for(int i=1; i<=9; i++)
        for(int j=1; j<=9; j++)
        {
            scanf("%d",&mp[i][j]);//已知输入
            if(!mp[i][j])continue;
            visrow[i][mp[i][j]]=1;
            viscol[j][mp[i][j]]=1;
            vispla[((i-1)/3)*3+(j-1)/3+1][mp[i][j]]=1;//可以好好体会一下计算宫的公式
        }
    flag=0;
    clock_t t1,t2;
    t1=clock();
    dfs(0);
    t2=clock();
    printf("time spent:%d\n",t2-t1);
    return 0;
}
/*
世界最难数独 跑的超级快
8 0 0 0 0 0 0 0 0
0 0 3 6 0 0 0 0 0
0 7 0 0 9 0 2 0 0
0 5 0 0 0 7 0 0 0
0 0 0 0 4 5 7 0 0
0 0 0 1 0 0 0 3 0
0 0 1 0 0 0 0 6 8
0 0 8 5 0 0 0 1 0
0 9 0 0 0 0 4 0 0
*/

 

公開された37元の記事 ウォン称賛14 ビュー10000 +

おすすめ

転載: blog.csdn.net/swust5120166213/article/details/104435516