八皇后的解法

来源:互联网 发布:2017淘宝怎么玩 编辑:程序博客网 时间:2024/04/30 10:43
 
8皇后用栈的解法。可以解N皇后,可以处理重复,可以输出到文件
  1. class Stack8Queen
  2. {
  3. public:
  4.     Stack8Queen(int siderLen = 8, bool bNoRepeat = false);
  5.     Stack8Queen(char * szFileName, int siderLen = 8, bool bNoRepeat = false);
  6.     ~Stack8Queen();
  7.     bool PushStack(int a);
  8.     bool PopStack(int &a);
  9.     bool CanPut(int num);
  10.     void PrintChessboard(int NO);
  11.     void AssignChessboard();
  12.     bool NoRepeatMatrix();
  13.     void SaveMatrix();
  14. private:
  15.     int *m_pdata;
  16.     int m_top;
  17.     FILE *m_pfLog;
  18.     int m_SiderLen;
  19.     int m_count;
  20.     int *m_pAllData;
  21.     bool m_bNoRepeat;
  22. };
  23. int _tmain(int argc, _TCHAR* argv[])
  24. {
  25.     Stack8Queen queen8(8, true);
  26.     //Stack8Queen queen8(9);
  27.     queen8.AssignChessboard();
  28.     return 0;
  29. }
  30. /////Class Stack8Queen
  31. Stack8Queen::Stack8Queen(int siderLen, bool bNoRepeat)
  32. {
  33.     m_SiderLen = siderLen;
  34.     m_pdata = new int[m_SiderLen];
  35.     for (int i=0; i<m_SiderLen; i++)
  36.     {
  37.         m_pdata[i] = 0;
  38.     }
  39.     m_top = -1;
  40.     m_pfLog = NULL;
  41.     m_count = 0;
  42.     m_bNoRepeat = bNoRepeat;
  43.     m_pAllData = NULL;
  44.     if (m_bNoRepeat)
  45.     {
  46.         m_pAllData = new int[100*m_SiderLen];
  47.         memset(m_pAllData, 0, 100 * m_SiderLen * sizeof(int));
  48.     }
  49. }
  50. Stack8Queen::Stack8Queen(char * szFileName, int siderLen, bool bNoRepeat)
  51. {
  52.     m_SiderLen = siderLen;
  53.     m_pdata = new int[m_SiderLen];
  54.     for (int i=0; i<m_SiderLen; i++)
  55.     {
  56.         m_pdata[i] = 0;
  57.     }
  58.     m_top = -1;
  59.     m_pfLog = fopen(szFileName, "w+");
  60.     m_count = 0;
  61.     m_bNoRepeat = bNoRepeat;
  62.     m_pAllData = NULL;
  63.     if (m_bNoRepeat)
  64.     {
  65.         m_pAllData = new int[100*m_SiderLen];
  66.         memset(m_pAllData, 0, 100 * m_SiderLen * sizeof(int));
  67.     }
  68. }
  69. Stack8Queen::~Stack8Queen()
  70. {
  71.     if (m_pfLog != NULL)
  72.     {
  73.         fclose(m_pfLog);
  74.         m_pfLog = NULL;
  75.     }
  76.     delete [] m_pdata;
  77.     if (m_pAllData != NULL)
  78.     {
  79.         delete [] m_pAllData;
  80.     }
  81. }
  82. bool Stack8Queen::PushStack(int a)
  83. {
  84.     if (m_top < m_SiderLen-1)
  85.     {
  86.         m_top++;
  87.         m_pdata[m_top] = a;
  88.         return true;
  89.     }
  90.     return false;
  91. }
  92. bool Stack8Queen::PopStack(int &a)
  93. {
  94.     if (m_top >= 0)
  95.     {
  96.         a = m_pdata[m_top];
  97.         m_top--;
  98.         return true;
  99.     }
  100.     return false;
  101. }
  102. bool Stack8Queen::CanPut(int num)
  103. {
  104.     for (int i=0; i <= m_top; i++)
  105.     {
  106.         if (m_pdata[i] == num || (m_top + 1 - i) == (num - m_pdata[i]) || (m_top + 1 + num) == (i + m_pdata[i]))
  107.         {
  108.             return false;
  109.         }
  110.     }
  111.     return true;
  112. }
  113. void Stack8Queen::PrintChessboard(int NO)
  114. {
  115.     if (m_pfLog == NULL)
  116.     {
  117.         printf("=== %d: ===/n", NO);
  118.         for (int i=0; i<m_SiderLen; i++)
  119.         {
  120.             for (int j=0; j<m_pdata[i]; j++)
  121.             {
  122.                 printf(". ");
  123.             }
  124.             printf("Q ");
  125.             for (int j=m_pdata[i]+1; j<m_SiderLen; j++)
  126.             {
  127.                 printf(". ");
  128.             }
  129.             printf("/n");
  130.         }
  131.         printf("--------------------------/n");
  132.     }
  133.     else
  134.     {
  135.         fprintf(m_pfLog, "=== %d: ===/n", NO);
  136.         for (int i=0; i<m_SiderLen; i++)
  137.         {
  138.             for (int j=0; j<m_pdata[i]; j++)
  139.             {
  140.                 fprintf(m_pfLog, ". ");
  141.             }
  142.             fprintf(m_pfLog, "Q ");
  143.             for (int j=m_pdata[i]+1; j<m_SiderLen; j++)
  144.             {
  145.                 fprintf(m_pfLog, ". ");
  146.             }
  147.             fprintf(m_pfLog, "/n");
  148.         }
  149.         fprintf(m_pfLog, "--------------------------/n");
  150.     }
  151. }
  152. void Stack8Queen::AssignChessboard()
  153. {
  154.     int iBegin = 0;
  155.     int i, j;
  156.     for (i=0; i<m_SiderLen;)
  157.     {
  158.         for (j=iBegin; j<m_SiderLen; j++)
  159.         {
  160.             if (CanPut(j))
  161.             {
  162.                 PushStack(j);
  163.                 break;
  164.             }
  165.         }
  166.         if (j == m_SiderLen)
  167.         {
  168.             if (PopStack(iBegin))
  169.             {
  170.                 iBegin++;
  171.                 i--;
  172.             }
  173.             else
  174.             {
  175.                 (m_pfLog == NULL) ? printf("ALL OVER!!/n") : fprintf(m_pfLog, "ALL OVER!!/n");
  176.                 printf("count result: %d /n", m_count);
  177.                 return;
  178.             }
  179.         }
  180.         else
  181.         {
  182.             iBegin = 0;
  183.             i++;
  184.         }
  185.         if (i == m_SiderLen)//succeed
  186.         {
  187.             //判断, 存储
  188.             if(m_bNoRepeat)
  189.             {
  190.                 if (NoRepeatMatrix())
  191.                 {
  192.                     SaveMatrix();
  193.                     m_count++;
  194.                     PrintChessboard(m_count);
  195.                 }
  196.             }
  197.             else
  198.             {
  199.                 m_count++;
  200.                 PrintChessboard(m_count);
  201.             }
  202.             PopStack(iBegin);
  203.             iBegin++;
  204.             i--;
  205.         }
  206.     }
  207. }
  208. void Stack8Queen::SaveMatrix()
  209. {
  210.     for (int i = 0; i < m_SiderLen; i++)
  211.     {
  212.         m_pAllData[m_SiderLen * m_count + i] = m_pdata[i];
  213.     }
  214. }
  215. bool Stack8Queen::NoRepeatMatrix()
  216. {
  217.     int * pTmpData = new int [m_SiderLen];
  218.     memset(pTmpData, 0, m_SiderLen * sizeof(int));
  219.     bool bNotRepeat = false;
  220.     //左右对称
  221.     for (int i=0; i<m_SiderLen; i++)
  222.     {
  223.         pTmpData[i] = m_SiderLen - 1 - m_pdata[i];
  224.     }
  225.     for (int i = 0; i < m_count; i++)
  226.     {
  227.         bNotRepeat = false;
  228.         for (int j=0; j<m_SiderLen; j++)
  229.         {
  230.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  231.             {
  232.                 bNotRepeat = true;
  233.                 break;
  234.             }
  235.         }
  236.         if (!bNotRepeat)
  237.         {
  238.             delete [] pTmpData;
  239.             pTmpData = NULL;
  240.             return false;
  241.         }
  242.     }
  243.     
  244.     //上下对称
  245.     for (int i=0; i<m_SiderLen; i++)
  246.     {
  247.         pTmpData[m_SiderLen - 1 - i] = m_pdata[i];
  248.     }
  249.     for (int i = 0; i < m_count; i++)
  250.     {
  251.         bNotRepeat = false;
  252.         for (int j=0; j<m_SiderLen; j++)
  253.         {
  254.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  255.             {
  256.                 bNotRepeat = true;
  257.                 break;
  258.             }
  259.         }
  260.         if (!bNotRepeat)
  261.         {
  262.             delete [] pTmpData;
  263.             pTmpData = NULL;
  264.             return false;
  265.         }
  266.     }
  267.     //中心对称,对角线
  268.     for (int i=0; i<m_SiderLen; i++)
  269.     {
  270.         pTmpData[m_SiderLen - 1 - i] = m_SiderLen - 1 - m_pdata[i];
  271.     }
  272.     for (int i = 0; i < m_count; i++)
  273.     {
  274.         bNotRepeat = false;
  275.         for (int j=0; j<m_SiderLen; j++)
  276.         {
  277.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  278.             {
  279.                 bNotRepeat = true;
  280.                 break;
  281.             }
  282.         }
  283.         if (!bNotRepeat)
  284.         {
  285.             delete [] pTmpData;
  286.             pTmpData = NULL;
  287.             return false;
  288.         }
  289.     }
  290.     //逆时针90度
  291.     for (int i=0; i<m_SiderLen; i++)
  292.     {
  293.         pTmpData[m_SiderLen - 1 - m_pdata[i]] = i;
  294.     }
  295.     for (int i = 0; i < m_count; i++)
  296.     {
  297.         bNotRepeat = false;
  298.         for (int j=0; j<m_SiderLen; j++)
  299.         {
  300.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  301.             {
  302.                 bNotRepeat = true;
  303.                 break;
  304.             }
  305.         }
  306.         if (!bNotRepeat)
  307.         {
  308.             delete [] pTmpData;
  309.             pTmpData = NULL;
  310.             return false;
  311.         }
  312.     }
  313.     //逆时针90度,然后左右对称 
  314.     for (int i=0; i<m_SiderLen; i++)
  315.     {
  316.         pTmpData[m_SiderLen - 1 - m_pdata[i]] = m_SiderLen - 1 - i;
  317.     }
  318.     for (int i = 0; i < m_count; i++)
  319.     {
  320.         bNotRepeat = false;
  321.         for (int j=0; j<m_SiderLen; j++)
  322.         {
  323.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  324.             {
  325.                 bNotRepeat = true;
  326.                 break;
  327.             }
  328.         }
  329.         if (!bNotRepeat)
  330.         {
  331.             delete [] pTmpData;
  332.             pTmpData = NULL;
  333.             return false;
  334.         }
  335.     }
  336.     //逆时针90度,然后上下对称 
  337.     for (int i=0; i<m_SiderLen; i++)
  338.     {
  339.         pTmpData[m_pdata[i]] = i;
  340.     }
  341.     for (int i = 0; i < m_count; i++)
  342.     {
  343.         bNotRepeat = false;
  344.         for (int j=0; j<m_SiderLen; j++)
  345.         {
  346.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  347.             {
  348.                 bNotRepeat = true;
  349.                 break;
  350.             }
  351.         }
  352.         if (!bNotRepeat)
  353.         {
  354.             delete [] pTmpData;
  355.             pTmpData = NULL;
  356.             return false;
  357.         }
  358.     }
  359.     //逆时针90度,180度中心对称 
  360.     for (int i=0; i<m_SiderLen; i++)
  361.     {
  362.         pTmpData[m_pdata[i]] = m_SiderLen - 1 - i;
  363.     }
  364.     for (int i = 0; i < m_count; i++)
  365.     {
  366.         bNotRepeat = false;
  367.         for (int j=0; j<m_SiderLen; j++)
  368.         {
  369.             if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
  370.             {
  371.                 bNotRepeat = true;
  372.                 break;
  373.             }
  374.         }
  375.         if (!bNotRepeat)
  376.         {
  377.             delete [] pTmpData;
  378.             pTmpData = NULL;
  379.             return false;
  380.         }
  381.     }
  382.     delete [] pTmpData;
  383.     pTmpData = NULL;
  384.     return true;
  385. }
 
原创粉丝点击