poj3076(16*16数独)
生活随笔
收集整理的這篇文章主要介紹了
poj3076(16*16数独)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自:http://blog.csdn.net/lyhypacm/article/details/5923287
題意:
一個16*16的數獨問題。
思路:
和poj3024一樣,就改點東西。
代碼:
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm>using namespace std;const int oo=0x3f3f3f3f; const int nR=16*16*16+10; const int nC=16*16*4; const int MAX=nR*4+nC+10; const int delta[]={1,16*16+1,16*16*2+1,16*16*3+1}; const int head=0;int cnt[nC+10],st[nC+10]; int left[MAX],right[MAX],up[MAX],down[MAX]; int row[MAX],col[MAX]; struct Ans {int r,c,k; }ans[MAX]; int M,K;void remove(const int& c) {left[right[c]]=left[c];right[left[c]]=right[c];for(int i=down[c];i!=c;i=down[i])for(int j=right[i];j!=i;j=right[j]){up[down[j]]=up[j];down[up[j]]=down[j];cnt[col[j]]--;} }void resume(const int& c) {for(int i=up[c];i!=c;i=up[i])for(int j=left[i];j!=i;j=left[j]){down[up[j]]=j;up[down[j]]=j;cnt[col[j]]++;}left[right[c]]=c;right[left[c]]=c; }bool dfs(const int& k) {if(right[head]==head){char s[300]={0};for(int i=0;i<k;i++)s[ans[st[i]].r*16+ans[st[i]].c]=ans[st[i]].k+'A';for(int i=0;i<16;i++){for(int j=0;j<16;j++){putchar(s[i*16+j]);}puts("");}return true;}int s=oo,c=0;for(int i=right[head];i!=head;i=right[i])if(cnt[i]<s){s=cnt[i];c=i;}remove(c);for(int i=down[c];i!=c;i=down[i]){st[k]=row[i];for(int j=right[i];j!=i;j=right[j])remove(col[j]);if(dfs(k+1))return true;for(int j=left[i];j!=i;j=left[j])resume(col[j]);}resume(c);return false; }void init() {left[head]=nC;right[head]=1;up[head]=down[head]=head;for(int i=1;i<=nC;i++){left[i]=i-1;right[i]=(i+1)%(nC+1);up[i]=down[i]=i;cnt[i]=0;col[i]=i;row[i]=0;}M=0;K=nC; }int makecolhead(const int& c) {K++;cnt[c]++;col[K]=c;row[K]=M;left[K]=right[K]=K;up[K]=c;down[K]=down[c];up[down[K]]=K;down[up[K]]=K;return K; }void addcol(const int& id,const int& c) {K++;cnt[c]++;col[K]=c;row[K]=M;left[K]=id;right[K]=right[id];left[right[K]]=K;right[left[K]]=K;up[K]=c;down[K]=down[c];up[down[K]]=K;down[up[K]]=K; }void addrow(const int& i,const int& j,const int& k) {int id;M++;ans[M].r=i;ans[M].c=j;ans[M].k=k;id=makecolhead(16*i+j+delta[0]);addcol(id,16*i+k+delta[1]);addcol(id,16*j+k+delta[2]);addcol(id,(i/4*4+j/4)*16+k+delta[3]); }int main() {char str[300];char s[300];int pos;bool blocks=false;while(~scanf("%s",str)){if(blocks)puts("");elseblocks=true;init();pos=0;for(int i=0;i<16;i++)s[pos++]=str[i];for(int i=1;i<16;i++){scanf("%s",str);for(int j=0;j<16;j++)s[pos++]=str[j];}for(int i=0;i<16;i++)for(int j=0;j<16;j++)if(s[i*16+j]=='-')for(int k=0;k<16;k++)addrow(i,j,k);elseaddrow(i,j,s[i*16+j]-'A');dfs(0);}return 0; }總結
以上是生活随笔為你收集整理的poj3076(16*16数独)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj3074(数独)
- 下一篇: hdu1532(最大流裸题)