8皇后用栈的解法。可以解N皇后,可以处理重复,可以输出到文件
- class Stack8Queen
- {
- public:
- Stack8Queen(int siderLen = 8, bool bNoRepeat = false);
- Stack8Queen(char * szFileName, int siderLen = 8, bool bNoRepeat = false);
- ~Stack8Queen();
- bool PushStack(int a);
- bool PopStack(int &a);
- bool CanPut(int num);
- void PrintChessboard(int NO);
- void AssignChessboard();
- bool NoRepeatMatrix();
- void SaveMatrix();
- private:
- int *m_pdata;
- int m_top;
- FILE *m_pfLog;
- int m_SiderLen;
- int m_count;
- int *m_pAllData;
- bool m_bNoRepeat;
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- Stack8Queen queen8(8, true);
- //Stack8Queen queen8(9);
- queen8.AssignChessboard();
- return 0;
- }
- /Class Stack8Queen
- Stack8Queen::Stack8Queen(int siderLen, bool bNoRepeat)
- {
- m_SiderLen = siderLen;
- m_pdata = new int[m_SiderLen];
- for (int i=0; i<m_SiderLen; i++)
- {
- m_pdata[i] = 0;
- }
- m_top = -1;
- m_pfLog = NULL;
- m_count = 0;
- m_bNoRepeat = bNoRepeat;
- m_pAllData = NULL;
- if (m_bNoRepeat)
- {
- m_pAllData = new int[100*m_SiderLen];
- memset(m_pAllData, 0, 100 * m_SiderLen * sizeof(int));
- }
- }
- Stack8Queen::Stack8Queen(char * szFileName, int siderLen, bool bNoRepeat)
- {
- m_SiderLen = siderLen;
- m_pdata = new int[m_SiderLen];
- for (int i=0; i<m_SiderLen; i++)
- {
- m_pdata[i] = 0;
- }
- m_top = -1;
- m_pfLog = fopen(szFileName, "w+");
- m_count = 0;
- m_bNoRepeat = bNoRepeat;
- m_pAllData = NULL;
- if (m_bNoRepeat)
- {
- m_pAllData = new int[100*m_SiderLen];
- memset(m_pAllData, 0, 100 * m_SiderLen * sizeof(int));
- }
- }
- Stack8Queen::~Stack8Queen()
- {
- if (m_pfLog != NULL)
- {
- fclose(m_pfLog);
- m_pfLog = NULL;
- }
- delete [] m_pdata;
- if (m_pAllData != NULL)
- {
- delete [] m_pAllData;
- }
- }
- bool Stack8Queen::PushStack(int a)
- {
- if (m_top < m_SiderLen-1)
- {
- m_top++;
- m_pdata[m_top] = a;
- return true;
- }
- return false;
- }
- bool Stack8Queen::PopStack(int &a)
- {
- if (m_top >= 0)
- {
- a = m_pdata[m_top];
- m_top--;
- return true;
- }
- return false;
- }
- bool Stack8Queen::CanPut(int num)
- {
- for (int i=0; i <= m_top; i++)
- {
- if (m_pdata[i] == num || (m_top + 1 - i) == (num - m_pdata[i]) || (m_top + 1 + num) == (i + m_pdata[i]))
- {
- return false;
- }
- }
- return true;
- }
- void Stack8Queen::PrintChessboard(int NO)
- {
- if (m_pfLog == NULL)
- {
- printf("=== %d: ===/n", NO);
- for (int i=0; i<m_SiderLen; i++)
- {
- for (int j=0; j<m_pdata[i]; j++)
- {
- printf(". ");
- }
- printf("Q ");
- for (int j=m_pdata[i]+1; j<m_SiderLen; j++)
- {
- printf(". ");
- }
- printf("/n");
- }
- printf("--------------------------/n");
- }
- else
- {
- fprintf(m_pfLog, "=== %d: ===/n", NO);
- for (int i=0; i<m_SiderLen; i++)
- {
- for (int j=0; j<m_pdata[i]; j++)
- {
- fprintf(m_pfLog, ". ");
- }
- fprintf(m_pfLog, "Q ");
- for (int j=m_pdata[i]+1; j<m_SiderLen; j++)
- {
- fprintf(m_pfLog, ". ");
- }
- fprintf(m_pfLog, "/n");
- }
- fprintf(m_pfLog, "--------------------------/n");
- }
- }
- void Stack8Queen::AssignChessboard()
- {
- int iBegin = 0;
- int i, j;
- for (i=0; i<m_SiderLen;)
- {
- for (j=iBegin; j<m_SiderLen; j++)
- {
- if (CanPut(j))
- {
- PushStack(j);
- break;
- }
- }
- if (j == m_SiderLen)
- {
- if (PopStack(iBegin))
- {
- iBegin++;
- i--;
- }
- else
- {
- (m_pfLog == NULL) ? printf("ALL OVER!!/n") : fprintf(m_pfLog, "ALL OVER!!/n");
- printf("count result: %d /n", m_count);
- return;
- }
- }
- else
- {
- iBegin = 0;
- i++;
- }
- if (i == m_SiderLen)//succeed
- {
- //判断, 存储
- if(m_bNoRepeat)
- {
- if (NoRepeatMatrix())
- {
- SaveMatrix();
- m_count++;
- PrintChessboard(m_count);
- }
- }
- else
- {
- m_count++;
- PrintChessboard(m_count);
- }
- PopStack(iBegin);
- iBegin++;
- i--;
- }
- }
- }
- void Stack8Queen::SaveMatrix()
- {
- for (int i = 0; i < m_SiderLen; i++)
- {
- m_pAllData[m_SiderLen * m_count + i] = m_pdata[i];
- }
- }
- bool Stack8Queen::NoRepeatMatrix()
- {
- int * pTmpData = new int [m_SiderLen];
- memset(pTmpData, 0, m_SiderLen * sizeof(int));
- bool bNotRepeat = false;
- //左右对称
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[i] = m_SiderLen - 1 - m_pdata[i];
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- //上下对称
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[m_SiderLen - 1 - i] = m_pdata[i];
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- //中心对称,对角线
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[m_SiderLen - 1 - i] = m_SiderLen - 1 - m_pdata[i];
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- //逆时针90度
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[m_SiderLen - 1 - m_pdata[i]] = i;
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- //逆时针90度,然后左右对称
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[m_SiderLen - 1 - m_pdata[i]] = m_SiderLen - 1 - i;
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- //逆时针90度,然后上下对称
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[m_pdata[i]] = i;
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- //逆时针90度,180度中心对称
- for (int i=0; i<m_SiderLen; i++)
- {
- pTmpData[m_pdata[i]] = m_SiderLen - 1 - i;
- }
- for (int i = 0; i < m_count; i++)
- {
- bNotRepeat = false;
- for (int j=0; j<m_SiderLen; j++)
- {
- if (m_pAllData[i*m_SiderLen + j] != pTmpData[j])
- {
- bNotRepeat = true;
- break;
- }
- }
- if (!bNotRepeat)
- {
- delete [] pTmpData;
- pTmpData = NULL;
- return false;
- }
- }
- delete [] pTmpData;
- pTmpData = NULL;
- return true;
- }