• 【DLX算法】poj2676 Sudoku


    DLX算法求解精确覆盖问题模板。赛场上可以参见白书。

    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int sub[10][10]={
    {0,0,0,0,0,0,0,0,0,0},
    {0,1,1,1,2,2,2,3,3,3},
    {0,1,1,1,2,2,2,3,3,3},
    {0,1,1,1,2,2,2,3,3,3},
    {0,4,4,4,5,5,5,6,6,6},
    {0,4,4,4,5,5,5,6,6,6},
    {0,4,4,4,5,5,5,6,6,6},
    {0,7,7,7,8,8,8,9,9,9},
    {0,7,7,7,8,8,8,9,9,9},
    {0,7,7,7,8,8,8,9,9,9}
    };
    int hlb[12],hub[12],llb[12],lub[12];
    const int maxn=4*9*9+5;
    const int maxr=9*9*9+5;
    const int maxnode=9*9*9*4+maxn+5;
    //ÐбàºÅ´Ó1¿ªÊ¼£¬ÁбàºÅΪ1~n£¬½áµã0ÊDZíÍ·½áµã£»½áµã1~nÊǸ÷Áж¥²¿µÄÐéÄâ½áµã 
    struct DLX{
    	int n,sz;//ÁÐÊý£¬½áµã×ÜÊý 
    	int S[maxn];//¸÷ÁнáµãÊý 
    	int row[maxnode],col[maxnode];//¸÷½áµãËùÔÚµÄÐÐÁбàºÅ 
    	int L[maxnode],R[maxnode],U[maxnode],D[maxnode];
    	int ansd,ans[maxr];//½â 
    	void init(int n){//nÊÇÁÐÊý 
    		this->n=n;
    		for(int i=0;i<=n;++i){
    			U[i]=i;
    			D[i]=i;
    			L[i]=i-1;
    			R[i]=i+1;
    		}
    		R[n]=0; L[0]=n;
    		sz=n+1;
    		memset(S,0,sizeof(S));
    	}
    	void addRow(int r,vector<int> columns){
    		int first=sz;
    		for(int i=0;i<columns.size();++i){
    			int c=columns[i];
    			L[sz]=sz-1;
    			R[sz]=sz+1;
    			D[sz]=c;
    			U[sz]=U[c];
    			D[U[c]]=sz;
    			U[c]=sz;
    			row[sz]=r;
    			col[sz]=c;
    			++S[c];
    			++sz;
    		}
    		R[sz-1]=first;
    		L[first]=sz-1;
    	}
    	//˳×ÅÁ´±íA£¬±éÀú³ýsÍâµÄÆäËûÔªËØ 
    	#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
    	void remove(int c){
    		L[R[c]]=L[c];
    		R[L[c]]=R[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;
    			}
    		}
    		L[R[c]]=c;
    		R[L[c]]=c;
    	}
    	bool dfs(int d){
    //		printf("%d",d);
    		if(R[0]==0){//ÕÒµ½½â 
    			ansd=d;//¼Ç¼½âµÄ³¤¶È 
    			return 1;
    		}
    		//ÕÒ½áµãÊý×îСµÄÁÐc 
    		int c=R[0];//µÚÒ»¸öδɾ³ýµÄÁÐ 
    		FOR(i,R,0){
    			if(S[i]<S[c]){
    				c=i;
    			}
    		}
    		remove(c);//ɾ³ýµÚcÁÐ 
    		FOR(i,D,c){//ÓýáµãiËùÔÚÐи²¸ÇµÚcÁÐ 
    			ans[d]=row[i];
    			FOR(j,R,i){
    				remove(col[j]);//ɾ³ý½áµãiËùÔÚÐÐÄܸ²¸ÇµÄËùÓÐÆäËûÁÐ 
    			}
    			if(dfs(d+1)){
    				return 1;
    			}
    			FOR(j,L,i){
    				restore(col[j]);//»Ö¸´½áµãiËùÔÚÐÐÄܸ²¸ÇµÄÆäËûËùÓÐÁÐ 
    			}
    		}
    		restore(c);//»Ö¸´µÚcÁÐ 
    		return 0;
    	}
    	bool solve(vector<int>& v){
    		v.clear();
    		if(!dfs(0)){
    			return 0;
    		}
    		for(int i=0;i<ansd;++i){
    			v.push_back(ans[i]);
    		}
    		return 1;
    	}
    }dlx;
    char s[12][12];
    int a[12][12];
    int mah[1005],mal[1005],mav[1005];
    int encode(int a,int b,int c){
        return a*81+b*9+c+1;
    }
    void decode(int code,int &a,int &b,int &c){
        --code;
        c=code%9;code/=9;
        b=code%9;code/=9;
        a=code;
    }  
    int main(){
    	int zu;
    //	freopen("poj2676.in","r",stdin);
    //	freopen("poj2676.out","w",stdout);
    	memset(hlb,0x7f,sizeof(hlb));
    	memset(llb,0x7f,sizeof(llb));
    	for(int i=1;i<=9;++i){
    		for(int j=1;j<=9;++j){
    			hlb[sub[i][j]]=min(hlb[sub[i][j]],i);
    			hub[sub[i][j]]=max(hub[sub[i][j]],i);
    			llb[sub[i][j]]=min(llb[sub[i][j]],j);
    			lub[sub[i][j]]=max(lub[sub[i][j]],j);
    		}
    	}
    	scanf("%d",&zu);
    	for(;zu;--zu){
    		for(int i=1;i<=9;++i){
    			scanf("%s",s[i]+1);
    		}
    		int hang=0,lie=0;
    		for(int i=1;i<=9;++i){
    			for(int j=1;j<=9;++j){
    				a[i][j]=s[i][j]-'0';
    			}
    		}
    		dlx.init(9*9*4);
    		for(int i=1;i<=9;++i){
    			for(int j=1;j<=9;++j){
    				for(int k=1;k<=9;++k){
    					if(!a[i][j] || a[i][j]==k){
    						vector<int> columns;
    						columns.push_back(encode(0,i-1,j-1));
    						columns.push_back(encode(1,i-1,k-1));
    						columns.push_back(encode(2,j-1,k-1));
    						columns.push_back(encode(3,sub[i][j]-1,k-1));
    						dlx.addRow(encode(i-1,j-1,k-1),columns);
    					}
    				}
    			}
    		}
    		vector<int> ans;
    		dlx.solve(ans);
    		for(int i=0;i<ans.size();++i){
    			int r,c,v;
    			decode(ans[i],r,c,v);
    			a[r+1][c+1]=v+1;
    		}
    		for(int i=1;i<=9;++i){
    			for(int j=1;j<9;++j){
    				printf("%d",a[i][j]);
    			}
    			printf("%d
    ",a[i][9]);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    hdu 4407 Sum 容斥+当前离线
    2014第11周二开发记
    2014第11周一word样式
    2014第10周日
    2014第10周六
    2014第10周杂想
    2014第10周四项目开发回顾提纲
    2014第10周三高效程序员的习惯
    2014第10周二程序员思维
    2014第10周一
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7752121.html
Copyright © 2020-2023  润新知