hdu4069 Squiggly Sudoku
来源:互联网 发布:淘宝店铺评估 编辑:程序博客网 时间:2024/06/13 03:10
解一个9*9的数独,行和列和普通数独一样需要出现1~9,但是它的小区域不是方形的,而是一个不规则的面积为9的图形。
DLX模版题。位运算和dfs处理小区域的边界就不说了。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-1)*9+num;}int mp[12][12];int sub[12][12];const int maxnode=270000;const int maxn=350;const int maxr=750;int anscnt;void init(){ anscnt=0; memset(sub,0,sizeof(sub));}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 ans2[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; } void dfs(int d){ if(anscnt>1)return; if(R[0]==0){ ansdep=d; anscnt++; memcpy(ans2,ans,sizeof(ans)); return; } 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]); } dfs(d+1); FOR(j,L,i){ restore(col[j]); } } restore(c); } }solver;void dfs(int nn,int mm,int val){ //找上下左右 //u16 r32 d64 l128 if(sub[nn][mm])return; sub[nn][mm]=val; if( (mp[nn][mm]&16)==0){ dfs(nn-1,mm,val); } if( (mp[nn][mm]&32)==0){ dfs(nn,mm+1,val); } if( (mp[nn][mm]&64)==0){ dfs(nn+1,mm,val); } if( (mp[nn][mm]&128)==0){ dfs(nn,mm-1,val); } }int main(){ int t; cin>>t; int cas=0; while(t--){ init(); cas++; for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ scanf("%d",&mp[i][j]); } } int subcnt=0; for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ if(!sub[i][j]){ dfs(i,j,++subcnt); } } } // for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ mp[i][j]&=15; } } solver.init(324); for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ for(int k=1;k<=9;k++){ if(mp[i][j]==k||mp[i][j]==0){ vector<int> vec; vec.push_back(encode(SLOT,i,j)); vec.push_back(encode(ROW,i,k)); vec.push_back(encode(COL,j,k)); vec.push_back(encode(SUB,sub[i][j],k)); solver.addrow( (i-1)*81+(j-1)*9+(k-1) ,vec); } } } } solver.dfs(0); printf("Case %d:\n",cas); if(anscnt==0){ printf("No solution\n"); }else if(anscnt==1){ for(int i=0;i<81;i++){ int tmp=solver.ans2[i]; int nn=tmp/81; tmp-=nn*81; int mm=tmp/9; int val=tmp%9; mp[nn+1][mm+1]=val+1; } for(int i=1;i<=9;i++){ for(int j=1;j<=9;j++){ printf("%d",mp[i][j]); }printf("\n"); } }else{ printf("Multiple Solutions\n"); } } return 0;}
0 0
- hdu4069 Squiggly Sudoku
- HDU4069-Squiggly Sudoku
- DLX精确覆盖 hdu4069 Squiggly Sudoku
- hdu 4069 squiggly sudoku
- HDU 4069 Squiggly Sudoku
- HDU 4069 Squiggly Sudoku DLX
- hdu4069
- HDOJ 4069 Squiggly Sudoku 精确覆盖+搜索
- HDU 4069 Squiggly Sudoku DLX 精确覆盖
- [DLX+bfs] hdu 4069 Squiggly Sudoku
- 【dfs预处理+DLX】hdu 4069 Squiggly Sudoku
- HDU 4069 Squiggly Sudoku 数独DLX 福州网络赛
- HDU 4069 Squiggly Sudoku【Dancing Links精确覆盖】
- HDU 4069 Squiggly Sudoku Dancing-Links(DLX)+Floodfill
- hdu 4069 Squiggly Sudoku——11年福州网络赛DLX
- HDU4069(未AC)
- DLX(变形数独)hdu4069
- Sudoku
- POJ 3468 【线段树区间更新-成段更新】
- java终结处理和垃圾回收
- java的一些date,calendar操作
- TYVJ p1011 传纸条
- UVA 11729 Commando War
- hdu4069 Squiggly Sudoku
- 数据库性能优化有哪些措施?
- 九、我们应当怎样做需求分析:功能角色分析与用例图
- iOS动画——啥?AutoLayout还能做动画?
- activity_main cannot be resolved or is not a field
- bzoj 3240 [Noi2013]矩阵游戏
- hihocoder #1107 : Shortest Proper Prefix
- android应用程序和数据库文件绑定
- UVA 1374 Power Calculus