日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 2676 Sudoku【DancingLinks,数独】

發(fā)布時間:2023/12/9 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 2676 Sudoku【DancingLinks,数独】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


http://poj.org/problem?id=2676
POJ 2676 Sudoku
也是求解規(guī)模為9*9的數(shù)獨問題,與POJ 3074 Sudoku相同的問題,只是修改了輸入輸出格式而已。。。
所以也不廢話了,嘿嘿。。。

#include<stdio.h> #include<string.h> const int MAX_COLOUMN = 81+9*9+9*9+9*9+2;//最多出現(xiàn)列數(shù) const int MAX_ROW = 81*9+2;//最多出現(xiàn)的列數(shù)int cnt[MAX_COLOUMN];//cnt[i]統(tǒng)計第i列1的個數(shù) int most,coloumn; bool ans[MAX_ROW];//ans存放最終選中的行 //跳舞鏈中的節(jié)點 struct Point {int up,down,left,right;//上,下,左,右int coloumn;//該點所在的列標int row;//行標 }node[MAX_ROW*MAX_COLOUMN+MAX_COLOUMN];//初始化跳舞鏈信息為空 void init(int m) {int i;for(i=0;i<=m;i++){node[i].down=i;node[i].up = i;node[i].coloumn=i;node[i].left=i-1;node[i].right=i+1;cnt[i]=0;}node[0].left = m;node[m].right = 0; }void remove(int c)//刪除c列上所有1元素所在的行 {node[node[c].right].left=node[c].left;node[node[c].left].right=node[c].right;int t,tt;for(t=node[c].down;t!=c;t=node[t].down)//從上到下從左到右刪除該列上的每一非零元素所在行信息{for(tt = node[t].right;tt!=t;tt=node[tt].right)//刪除非零元素所在行{cnt[node[tt].coloumn]--;node[node[tt].down].up = node[tt].up;node[node[tt].up].down = node[tt].down;}} }void resume(int c)//還原c列上所有1元素所在的行 {int t,tt;for(t=node[c].up;t!=c;t=node[t].up)//從下往上從左到右還原該c列中1所在的行信息{for(tt=node[t].left;tt!=t;tt=node[tt].left){cnt[node[tt].coloumn]++;node[node[tt].up].down=tt;node[node[tt].down].up=tt;}}node[node[c].right].left=c;node[node[c].left].right=c; }bool dfs(int k)//k為已經(jīng)選中的行的數(shù)目 {int i,j;if(k>=most)return false;if(node[coloumn].right == coloumn)//當前跳舞鏈已為空{(diào)if(k<most)most = k;return true;}int t = coloumn+1;int c;//選取當前矩陣中1最少的列for(i=node[coloumn].right;i!=coloumn;i=node[i].right){if(cnt[i]<t){c=i;t=cnt[i];if(t==1)break;}}remove(c);//刪除列c中所有1所在的行//刪除時從左到右從上到下,還原時從下到上,從右到左for(i = node[c].down;i!=c;i=node[i].down){for(j=node[i].right;j!=i;j=node[j].right){remove(node[j].coloumn);}ans[node[j].row]=true;if(dfs(k+1)){return true;}ans[node[j].row]=false;for(j=node[j].left;j!=i;j=node[j].left){resume(node[j].coloumn);}}resume(c);return false; } bool graph[MAX_ROW][MAX_COLOUMN]; void addrow(int i,int j,int k) {int curr = (i*9+j)*9+k;graph[curr][(i*9+j)]=true;graph[curr][81+i*9+k]=true;graph[curr][81+81+j*9+k]=true;int tr = i/3;int tc = j/3;graph[curr][81+81+81+(tr*3+tc)*9+k]=true; }char str[MAX_ROW]; int main() {int N,M,i,j,k;int T;while(scanf("%d",&T)!=EOF){while(T--){N=81*9;M = 9*9+9*9+9*9+9*9;coloumn = M;int cur=coloumn+1;//當前節(jié)點編號init(coloumn);memset(graph,0,sizeof(graph));for(i=0;i<9;i++){scanf("%s",str);for(j=0;j<9;j++){if(str[j]=='0'){for(k=0;k<9;k++)//遍歷每一種顏色{addrow(i,j,k);}continue;}k = str[j]-'1';addrow(i,j,k);}}for(i=0;i<N;i++){int start = cur;//記錄第i列的開始點編號int pre = cur;//記錄該列中當前1的左邊第一個1編號for(j=0;j<M;j++){// scanf("%d",&n);if(graph[i][j])//跳舞鏈中僅插入非0元素{int pos = j;node[cur].up = node[pos].up;node[node[pos].up].down = cur;node[cur].down = pos;node[pos].up = cur;cnt[pos]++;//該列1的個數(shù)+1node[cur].coloumn = pos;node[cur].left = pre;node[pre].right = cur;node[cur].right = start;node[start].left=cur;node[cur].row = i;pre=cur++;}}}most = N+1;//記錄最少需要選中的行數(shù)memset(ans,false,sizeof(ans));dfs(0);// printf("Yes, I found it\n");for(i=0;i<81;i++){ if(i!=0&&i%9==0)printf("\n");for(j=0;j<9;j++)if(ans[i*9+j]){printf("%d",j+1);break;}}printf("\n");}}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/AndreMouche/archive/2011/02/24/1964147.html

總結(jié)

以上是生活随笔為你收集整理的POJ 2676 Sudoku【DancingLinks,数独】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。