poj 3074 Sudoku

来源:互联网 发布:淘宝关键词的优化 编辑:程序博客网 时间:2024/05/08 16:41

        求一个9*9的数独的解,保证有唯一解。DLX模版题,做题的时候,我发现回溯时如果不是和搜的过程刚好逆回去的话,效率会降低不少,但这不影响正确性,不知道为什么。。。


#include <stdlib.h>  #include <iostream>  #include <stdio.h>  #include <string.h>  #include <vector>  using namespace std;         #define ll long long      const int SLOT = 0;  const int ROW = 1;  const int COL = 2;  const int SUB = 3;    int encode(int type,int id,int num){      return type*81+id*9+num+1;  }    char mp[90];    const int maxnode=270000;  const int maxn=350;  const int maxr=750;    struct dlx{      #define FOR(i,A,s) for(int i = A[s];i!=s;i=A[i])      int n,sz;      int U[maxnode],D[maxnode],L[maxnode],R[maxnode];      int row[maxnode],col[maxnode];            int S[maxn];    //各列节点数       int ans[maxr];      int ansdep;            void init(int n){          this->n=n;          sz=0;          memset(S,0,sizeof(S));                    for(int i=0;i<=n;i++){              U[i]=D[i]=i;              L[i]=i-1;    R[i]=i+1;              sz++;          }          L[0]=n;    R[n]=0;      }            void addrow(int r,vector<int> newrow){          int first=sz;          for(int i=0;i<newrow.size();i++){              int pos=newrow[i];              U[sz]=U[pos];    D[sz]=pos;              U[pos]=sz;              D[U[sz]]=sz;              row[sz]=r;              col[sz]=pos;              S[pos]++;              sz++;                    }          for(int i=first;i<sz;i++){              L[i]=i-1;    R[i]=i+1;          }          L[first]=sz-1;    R[sz-1]=first;      }            void remove(int c){          R[L[c]]=R[c];          L[R[c]]=L[c];          FOR(i,D,c){              FOR(j,R,i){                  U[D[j]]=U[j];    D[U[j]]=D[j];                  --S[col[j]];              }          }      }            void restore(int c){          FOR(i,U,c){              FOR(j,L,i){                  ++S[col[j]];                  U[D[j]]=j;    D[U[j]]=j;              }          }          R[L[c]]=c;          L[R[c]]=c;      }            bool dfs(int d){          if(R[0]==0){              ansdep=d;              return 1;          }                    int c=R[0];    //去满足一列           for(int i=c;i!=0;i=R[i]){              if(S[i]<S[c])c=i;          }          remove(c);          FOR(i,D,c){    //遍历这一列               ans[d]=row[i];              FOR(j,R,i){                  remove(col[j]);              }              if(dfs(d+1))return 1;              FOR(j,L,i){                  restore(col[j]);              }          }          restore(c);      return 0;}  }solver;    int main(){      while(cin>>mp){  if(mp[0]=='e'&&mp[1]=='n'&&mp[2]=='d')break;        solver.init(324);          for(int i=0;i<81;i++){             for(int k=1;k<=9;k++){                 if(mp[i]==k+'0'||mp[i]=='.'){                      vector<int> vec;                      vec.push_back(encode(SLOT,i/9,i%9));                      vec.push_back(encode(ROW,i/9,k-1));                      vec.push_back(encode(COL,i%9,k-1));                      vec.push_back(encode(SUB,i/27*3+(i%9)/3,k-1));                      solver.addrow( i*9+k-1 ,vec);                  }                              }          }                bool ok = solver.dfs(0);          for(int i=0;i<81;i++){              int tmp=solver.ans[i];              int pos=tmp/9;            mp[pos]=tmp%9+1+'0';        }          for(int i=0;i<81;i++){        printf("%c",mp[i]);        }cout<<endl;}      return 0;        }


0 0