zoukankan      html  css  js  c++  java
  • POJ 2676 Sudoku

    题目链接:http://poj.org/problem?id=2676

    数独问题。用dancing links解决。

    建图参考 http://wenku.baidu.com/link?url=3Tk5gVYew3mSQ2f2LxDODxPg3v-yqJPUaEkuZpfkHTxfSPQuM_n8TGl2Swp68XQY9MYN2BENZ-pmv9dpoh3Ulqt1lT-ZNo90jcJyi1eXasm

    要注意的就是搜索的时候 要先搜索 那一列中节点最少的,否则时间会很长。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <iomanip>
    using namespace std;
    int T;
    #define maxn 9*9*9*4+81*4+10
    int L[maxn], R[maxn], D[maxn], U[maxn];
    int H[maxn], C[maxn], ans[85], sum[81*4+10];
    int mp[10][10];
    int head, cnt;
    struct Node{
        int x, y, val;
    }hmap[9*9*9+10];
    void addnode(int x, int y, int val, int h){
        int pos1 = 81*0 + (x-1)*9+y;
        int pos2 = 81*1 + (x-1)*9 + val;
        int pos3 = 81*2 + (y-1)*9 + val;
        int pos4 = 81*3 + (((x-1)/3)*3 + (y-1)/3)*9 + val;
        
        H[cnt+1] = H[cnt+2] = H[cnt+3] = H[cnt+4] = h;
        C[cnt+1] = pos1; C[cnt+2] = pos2; C[cnt+3] = pos3; C[cnt+4] = pos4;
        
        R[cnt+1] = cnt+2; R[cnt+2] = cnt+3; R[cnt+3] = cnt+4; R[cnt+4] = cnt+1;
        L[cnt+1] = cnt+4; L[cnt+2] = cnt+1; L[cnt+3] = cnt+2; L[cnt+4] = cnt+3;
        
        D[U[pos1]] = cnt+1; D[cnt+1] = pos1;  U[cnt+1] = U[pos1]; U[pos1] = cnt+1;
        D[U[pos2]] = cnt+2; D[cnt+2] = pos2;  U[cnt+2] = U[pos2]; U[pos2] = cnt+2;
        D[U[pos3]] = cnt+3; D[cnt+3] = pos3;  U[cnt+3] = U[pos3]; U[pos3] = cnt+3;
        D[U[pos4]] = cnt+4; D[cnt+4] = pos4;  U[cnt+4] = U[pos4]; U[pos4] = cnt+4;
        
        sum[pos1]++; sum[pos2]++; sum[pos3]++; sum[pos4]++;
        cnt+=4;
        
        hmap[h].x = x; hmap[h].y = y; hmap[h].val = val;
    }
    void init(){
        memset(sum, 0, sizeof(sum));
        head = 0; cnt = 0;
        R[head] = 1; L[head] = 81*4;
        U[head] = head; D[head] = head;
        for(int i = 1; i <= 81*4; i++){  //头节点。 
            cnt++;
            H[cnt] = 0; C[cnt] = i;
            U[cnt] = cnt; D[cnt] = cnt;
            if(i == 81*4){
                R[cnt-1] = cnt; L[cnt] = cnt-1;
                R[cnt] = head;
            }
            else{
                R[cnt-1] = cnt; L[cnt] = cnt-1;
            }
        }
        int h = 0;
        for(int i = 1; i <= 9; i++){
            string temp; cin>>temp;
            for(int j = 0; j < 9; j++){
                if(temp[j] == '0'){
                    for(int k = 1; k <= 9; k++) addnode(i, j+1, k, ++h);
                }
                else{
                    addnode(i, j+1, int(temp[j]-'0'), ++h);
                }
            }
        }
    }
    void remove(int c){
        R[L[c]] = R[c]; L[R[c]] = L[c];
        for(int i = D[c]; i != c; i = D[i]){
            for(int j = R[i]; j != i; j = R[j]){
                U[D[j]] = U[j]; D[U[j]] = D[j];
                sum[C[j]]--;
            }
        }
    }
    void resume(int c){
        R[L[c]] = c;
        L[R[c]] = c;
        for(int i = D[c]; i != c; i = D[i]){
            for(int j = R[i]; j != i; j = R[j]){
                U[D[j]] = j;
                D[U[j]] = j;
                sum[C[j]]++;
            }
        }
    }
    bool dance(int k){
        int c = R[head];
        if(c == head){
            return true;
        }
        int min = 99999;
        for(int i = R[head];i != head; i = R[i]){
            if(sum[i]<=min){
                min = sum[i];
                c = i;
            }
        }
        remove(c);
        for(int i = D[c]; i != c; i = D[i]){
            ans[k] = H[i];
            for(int j = R[i]; j != i; j = R[j]) remove(C[j]);
            if(dance(k+1)) return true;
            for(int j = L[i]; j != i; j = L[j]) resume(C[j]);
        } 
        resume(c);
        return false;    
    }
    int main(){
        scanf("%d", &T);
        while(T--){
            init();    
            bool flag = dance(0);        
            for(int i = 0; i < 81; i++){
                mp[hmap[ans[i]].x][hmap[ans[i]].y] = hmap[ans[i]].val;
            }
            for(int i = 1; i <= 9; i++){
                for(int j = 1; j <= 9; j++){
                    printf("%d", mp[i][j]);
                }
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    树莓派相关知识
    yum mysql 需要:libsasl2.so.2()(64bit)的解决办法
    python 虚拟环境
    pip 查看某个包有哪些版本并升级
    C# DiagnosticSource and DiagnosticListener
    C# IObservable与IObserver观察者模式
    Visual Studio编译正常,但仍显示红线(Visual studio compiles fine but still shows red lines)
    查看PDB Guid 工具 dumpbin.exe 路径
    VMware vSphere 7.0 安装教程
    gacutil.exe 文件路径
  • 原文地址:https://www.cnblogs.com/titicia/p/4452051.html
Copyright © 2011-2022 走看看