dancing link 资料

http://blog.csdn.net/mu399/article/details/7627862  问题转化为 精确覆盖的方法

http://www.cnblogs.com/grenet/p/3145800.html  dancing link 详细说明,VB实现


DancingLinks的应用

        把dancingLink应用于实际问题时,只有一个难点,就是如何把具体的问题转换为可以精确覆盖的01矩阵模型,一旦完成了这个步后,直接套用模板就可以解决问题了。

应用之一:伤脑筋十二块               

伤脑筋十二块是dancing links精确覆盖的典型应用,理解起来最容易      


图2,12片5格骨牌的拼图

题目描述:         

给你12个如上图的5格骨牌,如何让程序拼出如上的“口”字图形。          

上图是题目的一个答案,你知道程序如何得到这个答案的吗?没错,就是用dancinglink的精确覆盖             

我们想象一个有72列的矩阵,其中12列是12个骨牌,剩下60列是60个非中心部分的格子,构造出         

所有可能的行来代表在一块骨牌在棋盘上得放置方案;每行有一些‘’1“,用来标识被覆盖的格子,5个1标识一个骨牌放置的位置(恰有1568个这样的行)             

我们将最前面的12列命名为F,I,L,P,N,T,U,V,W,X,Y,Z,并且我们可以用两个数字i,j给矩阵中对应棋盘上的第i行第j列格子的那一列命名。通过给出那些出现了‘’1"的列的名字,可以很方便地表示每一行。        

例如,图2就是与下面12行的对应的精确覆盖。            


1568个行指的是12个骨牌可放置方案的总和,比如长条骨牌I共有64种放置方案,1568中就包含了这64种                              

这1568行中,每行都有6个1,分布在72个列中                                 

这个矩阵的构造思路是:                                  

首先找约束关系,这里只有两个约束关系,                              

(1)12个骨牌,每种只有1个,                                 

(2)60个空格中,一个位置只能放一种骨牌(否则就要重叠着放了)                                

因为第一个约束关系,有了12个列来区分骨牌种类,因为第二个约束关系,有了60个选5个来表示骨牌放置    

应用之二:数独问题 sudoku           

解数独,生成数独,都可以使用精确覆盖,要把数独问题构造成01矩阵还是有一定的难度           

首先找约束关系,这里只有四个约束关系,         

(1)81个格子中每个格子只能放一个数字  

(2)每一行的数字不能重复      

(3)每一列的数字不能重复      

(4)每一九宫内的数字不能重复


四个约束关系中,每个约束对应一个列域,对于第二个约束关系,数独中共有9行,每行可以填9个不同的数字       

因此第二个列域,共有9* 9,81个列,依此类推,数独问题共有列324个。            

由于81个格子,每个格子都最多有9种选择,所以行最多有81*9=729行             

这样01矩阵的每行都有4个1,第一个1分布在1到81列,第二个1分布在82到162列,第三个1分布在163到243列,        

最后一个1分布在其余列区域。 

 

思考:为什么不能这样构造01矩阵,用5个1,第一个1表示格子序号,有81个列,第二个1表示数字,从1到9有9个列,第三个1表示行号,有9行,第四个1表示列号也有9个,第五个1表示九宫格序号,也有9个,这样共有117列。            

        

为了便于理解,举个例子             

    9,2,0,0,0,0,0,0,0,        

    5,0,0,8,7,0,0,0,0,        

    0,3,8,0,9,1,0,0,0,        

    0,5,2,9,3,0,1,6,0,        

    0,9,0,0,0,0,0,3,0,        

    0,7,3,0,6,4,9,8,0,        

    0,0,0,4,1,0,2,5,0,        

    0,0,0,0,5,3,0,0,1,        

    0,0,0,0,0,0,0,7,3         

如上数独有空格40个,已知格子41个,把这个数独构造成01矩阵,矩阵的行有             

40*9+41  共401行    

对于第一个数字9,在1到81列的第一列,在82到162列的第9个,即90列,在163列到243列的第9个,在244到324列的第9个各占一个1           

对于第三个数字0,由于有9个选择,所以在构造01矩阵时,要向矩阵插入9个行,来表示各种可能             

        

对于数独的生成             

总体思路是一行一行的生成,第一行可以用一个随机的1到9的排列,接下来的8行,每行都要用dancinglink求解可行的排序             

(1)先对1到9这9个数进行随机排列,把这个排列作为数独终盘布局的第一行             

(2)自己写函数筛选出下一行,每个格子可以填写的数字集合,筛选时不用考虑行冲突        

比如对于排列5,9,7,4,2,6,8,3,1             

筛选结果如下:  123468,123468,123468,135789,135789,135789,245679,245679,245679  

表示对于下一行的1,2,3列,可以选择的数字集合有1,2,3,4,6,8.           

下一行的4,5,6列,可以选择的数字集合有1,3,5,7,8,9       

下一行的7,8,9列,可以选择的数字集合有2,4,5,6,7,9       

这时,构造01矩阵,就只有2个约束关系           

1       对于下一行的9个格子,每个格子只能放一个数字    

2       对于下一行的9个格子中的数字,每个数字都不能重复 

        

因为第3个和4个约束,已经在筛选时考虑进去,这里不需再多此一举          

这时的01矩阵,列有9+ 9=18个,行有6* 9 = 54行(6+6+6+6+6+6+6+6+6)。

 

应用之三:N皇后         

N皇后问题也可以转换为dancinglinks的精确覆盖问题           

这里只讲如何把n皇后问题转换为01矩阵,首先有四个约束关系             

(1)所有皇后不能在同一行       

(2)所有皇后不能在同一列       

(3)所有皇后不能在同一左斜线             

(4)所有皇后不能在同一右斜线             


为了便于理解,举个例子             

n=8时,有8行,8列,15个左斜线,15个右斜线(2*n-1)           

这样构造的矩阵有46个列,8*8=64个行       

矩阵的每行都有4个1,分别分布在行域,列域,左斜线域,右斜线域           

在编程求解这个问题时,需要做一点变通,因为左斜线域,右斜线域的列不可能被全部覆盖         

因此只需行域和列域被完全覆盖就算找到问题的一个解了。


附:

dancing LInks 求解数独的C++代码

  1. #include<iostream>  
  2. #include<string.h>  
  3.   
  4. using namespace std;  
  5.   
  6.   
  7. struct Node   
  8. {  
  9.     Node *up;  
  10.     Node *down;  
  11.     Node *left;  
  12.     Node *right;  
  13.     Node *colRoot; //列首  
  14.     int row; //所在行  
  15.     int sum; //此列节点总数  
  16. };  
  17.   
  18. #define R 729  
  19. #define C 324  
  20.   
  21.   
  22. class Dlx  
  23. {  
  24. public:  
  25.     Node *nodes,*row,*col,*head;//可用节点,行首,列首,总头节点  
  26.     int rowNum,colNum,nodeCount;//行数,列数,总节点数  
  27.     int *result,resultCount;//结果,结果行数  
  28.   
  29.     Dlx()  
  30.     {  
  31.         nodes=new Node[R*C];//直接用数组竟然运行不起,栈溢出了,还得放在堆里  
  32.         row=new Node[R];  
  33.         col=new Node[C+1];  
  34.         result=new int[R];  
  35.     }  
  36.     ~Dlx()  
  37.     {  
  38.         delete []nodes;  
  39.         delete []row;  
  40.         delete []col;  
  41.         delete []result;  
  42.   
  43.     }  
  44.     void init(int r,int c);//初始化  
  45.     void cover(Node *t);//覆盖一列  
  46.     void uncover(Node *t);//取消覆盖  
  47.     bool solove(int k=0);//搜索出结果  
  48.     void addNode(int r,int c);//添加一个节点  
  49. };  
  50.   
  51.   
  52. void Dlx::init(int r,int c)  
  53. {  
  54.     int i;  
  55.       
  56.     rowNum=r;  
  57.     colNum=c;  
  58.     //将各列连起来,col[colNum]为总头节点  
  59.     for(i=0;i<=colNum;i++)  
  60.     {  
  61.         col[i].up=col[i].down=col+i;  
  62.         col[i].left=col + (i+colNum)%(1+colNum);  
  63.         col[i].right=col + (i+1)%(1+colNum);  
  64.         col[i].sum=0;  
  65.     }  
  66.     head=col+colNum;  
  67.   
  68.     //将各行节点数清零  
  69.     for(i=0;i<rowNum;i++)  
  70.     {  
  71.         row[i].up=row[i].down=row[i].left=row[i].right=row[i].colRoot=row+i;  
  72.     }  
  73.       
  74.     nodeCount=0;//总节点数清零  
  75. }  
  76.   
  77. void Dlx::addNode(int r,int c)  
  78. {  
  79.     nodes[nodeCount].up=col[c].up;  
  80.     nodes[nodeCount].down=col+c;  
  81.     nodes[nodeCount].left=row[r].left;  
  82.     nodes[nodeCount].right=row+r;  
  83.     nodes[nodeCount].row=r;  
  84.     nodes[nodeCount].colRoot=col+c;  
  85.     col[c].up=col[c].up->down=row[r].left=row[r].left->right=nodes+nodeCount++;     
  86.     col[c].sum++;  
  87. }  
  88.   
  89.   
  90. void Dlx::cover(Node *t)  
  91. {  
  92.     Node *p,*q;  
  93.     t->left->right=t->right;  
  94.     t->right->left=t->left;  
  95.     for(p=t->down;p!=t;p=p->down)  
  96.     {  
  97.         for(q=p->right;q!=p;q=q->right)  
  98.         {  
  99.             q->up->down=q->down;  
  100.             q->down->up=q->up;  
  101.             q->colRoot->sum--;  
  102.         }  
  103.     }     
  104. }  
  105.   
  106. void Dlx::uncover(Node *t)  
  107. {  
  108.     Node *p,*q;  
  109.     for(p=t->up;p!=t;p=p->up)  
  110.     {  
  111.         for(q=p->left;q!=p;q=q->left)  
  112.         {  
  113.             q->up->down=q->down->up=q;  
  114.             q->colRoot->sum++;  
  115.         }  
  116.     }  
  117.     t->left->right=t->right->left=t;  
  118. }  
  119.   
  120. bool Dlx::solove(int k)  
  121. {  
  122.     //是否还有未覆盖的列  
  123.     if(head->right==head)  
  124.     {  
  125.         //记录完成覆盖所用行数  
  126.         resultCount=k;  
  127.         return true;  
  128.     }  
  129.       
  130.     Node *pMin,*p,*q;  
  131.     //找到节点数最少的一列,并覆盖  
  132.     for(pMin=head->right,p=pMin->right;p!=head;p=p->right)  
  133.     {  
  134.         if(pMin->sum>p->sum)  
  135.             pMin=p;  
  136.     }  
  137.     cover(pMin);  
  138.       
  139.   
  140.     for(p=pMin->down;p!=pMin;p=p->down)  
  141.     {  
  142.         result[k]=p->row;  
  143.         //选定此列上的一个节点,将此节点所在行上所有节点的对应列进行覆盖  
  144.         for(q=p->right;q!=p;q=q->right)  
  145.             cover(q->colRoot);  
  146.         if(solove(k+1))  
  147.             return true;  
  148.         //如果不能成功,则取消覆盖  
  149.         for(q=p->left;q!=p;q=q->left)  
  150.             uncover(q->colRoot);  
  151.     }  
  152.   
  153.     uncover(pMin);  
  154.     return false;  
  155. }  
  156. int getRowIndex(int rowNum)  
  157. {  
  158.     int num = rowNum%9;  
  159.     int rowIndex = rowNum / 81;  
  160.     return 81 + rowIndex*9 + num;  
  161. }  
  162. int getColIndex(int rowNum)  
  163. {  
  164.     int num = rowNum%9;  
  165.     int index = rowNum/9;   //位置  
  166.     int colIndex = index%9;  
  167.     return 162 + colIndex*9+num;  
  168. }  
  169. int getSquareIndex(int rowNum)  
  170. {  
  171.     int num = rowNum%9;  
  172.     int index = rowNum/9;   //位置  
  173.     int rowIndex = index / 9;  
  174.     int colIndex = index%9;  
  175.     int squareIndex = int(rowIndex/3)*3 + colIndex/3;  
  176.     return 243 + squareIndex*9+num;  
  177. }  
  178. int main3()  
  179. {  
  180.     int i,j;  
  181.     int node4=0;  
  182.     char str[82];  
  183.     Dlx dlx;  
  184.       
  185.     //cin>>n;  
  186.     dlx.init(729,324);  
  187.     //for(i=0;i<9;i++)  
  188.     //{  
  189.     //  cin>> (str+i*9);  
  190.     //}  
  191.     //......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.  
  192.     const char *input = ".2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.";  
  193.     strcpy(str,input);  
  194.     for(i=0;i<729;i++)  
  195.     {  
  196.         //cout << "row=>" << i << "\tcol=> 位置" << i/9 <<"\t行"<<81+i/9/9*9+i%9<<"\t列"<<162+i/9%9*9+i%9<<"\t块"<< 243+(i/9/9/3*3+i/9%9/3)*9+i%9;  
  197.         //cout << "row=>" << i << "\tcol=> 位置" << i/9 <<"\t行"<<getRowIndex(i)<<"\t列"<<getColIndex(i)<<"\t块"<<getSquareIndex(i);  
  198.         if(str[i/9]=='.' || str[i/9]-'1'==i%9)  
  199.         {  
  200.             node4++;  
  201.             int rowIndex = i;  
  202.             int colIndex = i/9;  
  203.             dlx.addNode(rowIndex,colIndex);//位置冲突  
  204.   
  205.             dlx.addNode(rowIndex,getRowIndex(i));//行冲突  
  206.   
  207.             dlx.addNode(rowIndex,getColIndex(i));//列冲突  
  208.   
  209.             dlx.addNode(rowIndex,getSquareIndex(i));//块冲突  
  210.         //  cout << "\t<=";  
  211.         }  
  212.         //cout << endl;  
  213.     }  
  214.     if(dlx.solove())  
  215.     {  
  216.         //结果存到字符串中  
  217.         for(i=0;i<81;i++)  
  218.         {  
  219.             j=dlx.result[i];  
  220.             str[j/9]='1'+j%9;  
  221.         }  
  222.         //输出字符串  
  223.         for(i=0;i<9;i++)  
  224.         {  
  225.             for(j=0;j<9;j++)  
  226.                 cout<<str[i*9+j];  
  227.             cout<<endl;  
  228.         }  
  229.     }  
  230.       
  231.     return 0;  
  232. }  

附,生成数独终盘布局的Flex代码

[plain] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"   
  3.                        xmlns:s="library://ns.adobe.com/flex/spark"   
  4.                        xmlns:mx="library://ns.adobe.com/flex/mx">  
  5.     <fx:Declarations>  
  6.         <!-- Place non-visual elements (e.g., services, value objects) here -->  
  7.     </fx:Declarations>  
  8.     <fx:Script>  
  9.         <![CDATA[  
  10.             import model.DancingNode;  
  11.               
  12.             private var sample:String="1279,2367,1369,24789,4578,259,13458,1368,456";  
  13.               
  14.             private var rowArr:Array=[];  
  15.             private var colArr:Array=[];  
  16.             private var head:DancingNode;  
  17.             private var nodes:Array=[];  
  18.             private var cnt:Array=[];  
  19.             private var answer:Array=[];  
  20.             private var answerArr:Array=[];  
  21.               
  22.             private function _init(restrict:String):void  
  23.             {  
  24.                 answerArr=[];  
  25.                 answer=[];  
  26.                 cnt=[];  
  27.                 nodes=[];  
  28.                 rowArr=[];  
  29.                 colArr=[];  
  30.                 var i:int;  
  31.                 var colLen:int=18;  
  32.                 var rowLen:int=restrict.split(',').join('').length;  
  33.                 for(i=0;i<rowLen;i++)  
  34.                 {  
  35.                     var row:DancingNode = new DancingNode(i);  
  36.                     rowArr.push(row);  
  37.                 }  
  38.                 for(i=0;i<=colLen;i++)  
  39.                 {  
  40.                     var col:DancingNode = new DancingNode(-1,i);  
  41.                     colArr.push(col);  
  42.                     cnt.push(0);  
  43.                 }  
  44.                 var colArrLen:int = colArr.length;  
  45.                 for(i=0;i<colArr.length;i++)  
  46.                 {  
  47.                     var left:int = (i+colArrLen-1)%colArrLen;  
  48.                     var right:int = (i+1)%colArrLen;  
  49.                     DancingNode(colArr[i]).left=colArr[left];  
  50.                     DancingNode(colArr[i]).right=colArr[right];  
  51.                 }  
  52.                 head = colArr[0];  
  53.                   
  54.                 //create links  
  55.                 var rowIndex:int=0;  
  56.                 var arr1:Array = restrict.split(',');  
  57.                 for(i=0;i<arr1.length;i++)  
  58.                 {  
  59.                     var arr2:Array = String(arr1[i]).split('');  
  60.                     for(var j:int=0;j<arr2.length;j++)  
  61.                     {  
  62.                         var colIndex1:int=i+1;  
  63.                         var colIndex2:int=9+int(arr2[j]);  
  64.                         addNode(rowIndex,colIndex1,i,int(arr2[j]));  
  65.                         addNode(rowIndex,colIndex2,i,int(arr2[j]));  
  66.                         rowIndex++;  
  67.                     }  
  68.                 }  
  69.                 for(i=0;i<rowLen;i++)  
  70.                 {  
  71.                     DancingNode(rowArr[i]).left.right=DancingNode(rowArr[i]).right;  
  72.                     DancingNode(rowArr[i]).right.left=DancingNode(rowArr[i]).left;  
  73.                 }  
  74.             }  
  75.               
  76.             private function addNode(r:int,c:int,r1:int,c1:int):void  
  77.             {  
  78.                 var node:DancingNode = new DancingNode(r,c);  
  79.                 node.rowValue=r1;  
  80.                 node.colValue=c1;  
  81.                 node.up = colArr[c].up;  
  82.                 node.down = colArr[c];  
  83.                 node.left = rowArr[r].left;  
  84.                 node.right = rowArr[r];  
  85.                 cnt[c]++;  
  86.                   
  87.                 colArr[c].up=colArr[c].up.down=rowArr[r].left=rowArr[r].left.right=node;  
  88.                 nodes.push(node);  
  89.             }  
  90.               
  91.             private function remove(node:DancingNode):void  
  92.             {  
  93.                 //trace("remove=>",node.col);  
  94.                 node.left.right = node.right;  
  95.                 node.right.left = node.left;  
  96.                 for(var p:DancingNode=node.down;p!=node;p=p.down)  
  97.                 {  
  98.                     for(var q:DancingNode=p.right;q!=p;q=q.right)  
  99.                     {  
  100.                         q.up.down=q.down;  
  101.                         q.down.up=q.up;  
  102.                         cnt[q.col]--;  
  103.                     }  
  104.                 }  
  105.             }  
  106.               
  107.             private function resume(node:DancingNode):void  
  108.             {  
  109.                 //trace("resume=>",node.col);  
  110.                 for(var p:DancingNode=node.down;p!=node;p=p.down)  
  111.                 {  
  112.                     for(var q:DancingNode=p.right;q!=p;q=q.right)  
  113.                     {  
  114.                         q.up.down=q;  
  115.                         q.down.up=q;  
  116.                         cnt[q.col]++;  
  117.                     }  
  118.                 }  
  119.                 node.left.right = node;  
  120.                 node.right.left = node;  
  121.             }  
  122.               
  123.             private function dancing(depth:int):Boolean  
  124.             {  
  125.                 //是否还有未覆盖的列  
  126.                 if(head.right==head)  
  127.                 {  
  128.                     var arr:Array=[];  
  129.                     for(var i:int=0;i<answer.length;i++)  
  130.                     {  
  131.                         var node:DancingNode=answer[i];  
  132.                         arr[node.rowValue]=node.colValue;  
  133.                     }  
  134.                     answerArr.push(arr);  
  135.                     return true;  
  136.                 }  
  137.                 var pMin:DancingNode;  
  138.                 var p:DancingNode;  
  139.                 //找到节点数最少的一列,并覆盖  
  140.                 for(pMin=head.right,p=pMin.right;p!=head;p=p.right)  
  141.                 {  
  142.                     if(cnt[pMin.col] > cnt[p.col])  
  143.                     {  
  144.                         pMin = p;  
  145.                     }  
  146.                 }  
  147.                 remove(pMin);  
  148.                 var q:DancingNode;  
  149.                 for(p=pMin.down;p!=pMin;p=p.down)  
  150.                 {  
  151.                     //选定此列上的一个节点,将此节点所在行上所有节点的对应列进行覆盖  
  152.                     answer[depth]=p;  
  153.                     for(q=p.right;q!=p;q=q.right)  
  154.                     {  
  155.                         remove(colArr[q.col]);  
  156.                     }  
  157.                     if(dancing(depth+1))  
  158.                     {  
  159.                         if(answerArr.length > 10)  
  160.                         {  
  161.                             return true;  
  162.                         }  
  163.                     }  
  164.                     for(q=p.left;q!=p;q=q.left)  
  165.                     {  
  166.                         resume(colArr[q.col]);  
  167.                     }  
  168.                 }  
  169.                 resume(pMin);  
  170.                 if(answerArr.length > 0)  
  171.                 {  
  172.                     return true;  
  173.                 }  
  174.                 return false;  
  175.             }  
  176.               
  177.             private function getSudokuLine(restricts:Array):Array  
  178.             {  
  179.                 var arr:Array=[];  
  180.                 for(var i:int=0;i<restricts.length;i++)  
  181.                 {  
  182.                     arr.push((restricts[i] as Array).join(''));  
  183.                 }  
  184.                 _init(arr.join(','));  
  185.                 if(dancing(0))  
  186.                 {  
  187.                     var line:Array = answerArr[int(answerArr.length*Math.random())];  
  188.                     trace('getSudokuLine,answer length=>',answerArr.length);  
  189.                     return line;  
  190.                 }  
  191.                 return [];  
  192.             }  
  193.             //得到随机的1到9的排列  
  194.             private function getRandomArr(value:int):Array  
  195.             {  
  196.                 var bak:Array = [];  
  197.                 for(var i:int=1;i<=value;i++)  
  198.                 {  
  199.                     bak.push(i);  
  200.                 }  
  201.                 var randLine:Array=[];  
  202.                 while(bak.length>0)  
  203.                 {  
  204.                     var index:int = bak.length*Math.random();  
  205.                     randLine.push(bak[index]);  
  206.                     bak.splice(index,1);  
  207.                 }  
  208.                 return randLine;  
  209.             }  
  210.               
  211.             public function createFullSudoku():Array  
  212.             {  
  213.                 var sudokuArr:Array=[];  
  214.                 while(sudokuArr.length < 9)  
  215.                 {  
  216.                     sudokuArr=[];  
  217.                     sudokuArr.push(getRandomArr(9));  
  218.                     for(var i:int=0;i<8;i++)  
  219.                     {  
  220.                         var restricts:Array = getRestricts(sudokuArr);  
  221.                         if(restricts.length==0)  
  222.                         {  
  223.                             break;  
  224.                         }  
  225.                         var line:Array = getSudokuLine(restricts);  
  226.                         if(line.length==0)  
  227.                         {  
  228.                             break;  
  229.                         }  
  230.                         sudokuArr.push(line);  
  231.                     }  
  232.                 }  
  233.                 return sudokuArr;  
  234.             }  
  235.               
  236.             private function getRestricts(curLayout:Array):Array  
  237.             {  
  238.                 var i:int;  
  239.                 var ret:Array=[];  
  240.                 for(i=0;i<9;i++)  
  241.                 {  
  242.                     var arr:Array=getCandidateNums(curLayout,i);  
  243.                     if(arr.length==0)  
  244.                     {  
  245.                         return [];  
  246.                     }  
  247.                     ret.push(arr);  
  248.                 }  
  249.                 return ret;  
  250.             }  
  251.             //根据当前布局curLayout,得到index列的候选数集合  
  252.             private function getCandidateNums(curLayout:Array,index:int):Array  
  253.             {  
  254.                 var i:int;  
  255.                 var line:Array = [0,1,2,3,4,5,6,7,8,9];  
  256.                 if(curLayout.length==0)  
  257.                 {  
  258.                     return [1,2,3,4,5,6,7,8,9];  
  259.                 }  
  260.                 //列排除  
  261.                 for(i=0;i<curLayout.length;i++)  
  262.                 {  
  263.                     line[curLayout[i][index]]=0;  
  264.                 }  
  265.                 //九宫格排除  
  266.                 var col3_3:int = index/3;  
  267.                 var row3_3:int = curLayout.length/3;  
  268.                 var inRow3_3:int = curLayout.length%3;  
  269.                 for(i=row3_3*3;i<row3_3*3+inRow3_3;i++)  
  270.                 {  
  271.                     line[curLayout[i][col3_3*3] ]=0;  
  272.                     line[curLayout[i][col3_3*3+1] ]=0;  
  273.                     line[curLayout[i][col3_3*3+2] ]=0;  
  274.                 }  
  275.                 var ret:Array=[];  
  276.                 for(i=0;i<line.length;i++)  
  277.                 {  
  278.                     if(line[i]!=0)  
  279.                     {  
  280.                         ret.push(i);  
  281.                     }  
  282.                 }  
  283.                 return ret;  
  284.             }  
  285.               
  286.             private function createSudoku():void  
  287.             {  
  288.                 var arr:Array=createFullSudoku();  
  289.                 var arr2:Array=[];  
  290.                 for(var i:int=0;i<arr.length;i++)  
  291.                 {  
  292.                     arr2.push((arr[i] as Array).join(','));  
  293.                 }  
  294.                 area.text = arr2.join('\n');  
  295.             }  
  296.         ]]>  
  297.     </fx:Script>  
  298.     <s:VGroup horizontalCenter="0" verticalCenter="0">  
  299.         <s:TextArea width="300" height="300" id="area"/>  
  300.         <s:Button label="get full sudoku" click="createSudoku()"/>  
  301.     </s:VGroup>  
  302. </s:WindowedApplication>  

[plain] view plaincopy
  1. package model  
  2. {  
  3.     public class DancingNode  
  4.     {  
  5.         public var row:int;  
  6.         public var col:int;  
  7.         public var rowValue:int;  
  8.         public var colValue:int;  
  9.         public var up:DancingNode;  
  10.         public var down:DancingNode;  
  11.         public var left:DancingNode;  
  12.         public var right:DancingNode;  
  13.           
  14.         public function DancingNode(r:int=-1,c:int=-1)  
  15.         {  
  16.             row = r;  
  17.             col = c;  
  18.             up = this;  
  19.             down = this;  
  20.             left = this;  
  21.             right = this;  
  22.         }  
  23.     }  
  24. }  

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭