補充

// Sudoku.h: interface for the Sudoku class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SUDOKU_H__A3A5F740_4435_4643_A497_C7785C94B7E7__INCLUDED_)
#define AFX_SUDOKU_H__A3A5F740_4435_4643_A497_C7785C94B7E7__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning ( disable : 4786 )

#include <string>
#include <set>
#include <map>
#include <list>

using namespace std;


struct T_MapData {
    unsigned short m_usedNum;   // 使用了哪些數字
    unsigned short m_pos;       // 哪些位置未填
};

typedef struct ANSudoku_tag {
    int r;
    int c;
    int box_num;
} ANSudoku;

typedef struct ANSudokuCell_tag {
    int candi[9];   // 候選數數組
    int n;          // 候選數個數
    int m;          // 原始候選數個數
} ANSudokuCell;

#define SD_SIZE         9

struct _Point{
    int r;
    int c;
};

#define HOUSE_BOX   1
#define HOUSE_ROW   2
#define HOUSE_COL   4


class Sudoku 
{
public:
 Sudoku(string & strSudoku);
    Sudoku(int data[SD_SIZE][SD_SIZE]);
 virtual ~Sudoku();
      
    int Solve();
    int TrySolve();
   
    int SingleCandidature(int &r, int &c, bool bOnlyOne);
    int HiddenSingleCandi(int & rr, int &cc, bool bOnlyOne);
    int LockedCandidates();
    void SetNum(int r, int c, int n);
   
    // 顯式 數對(Naked Pair), 3數集(Naked Triple), 4數集(Naked Quad)
    void NakedNumSet(int n);
    void HiddenNumSet(int n);
    // X-Wing
    void X_Wing(int n = 2);
    void Bug_1();
    void XY_Wing();
    void XYZ_Wing();

    // Turbotfish 多寶魚(比目魚)
    void Turbotfish();


    // out put method
    // 取(r,c) 位置的所有候選數, 通過num[]輸出這些候選數
    // 返回值表示候選數的個數
    int  CandidatureNum(int r, int c, int num[]);
    void OutPut();
    void printfNum3();
   
    // 獲取p1和p2點可以共同看到的位置
    int GetInterSection(_Point &p1, _Point &p2, int n, _Point arrOut[]);

    void UniqueRectangle();

private:
    void SetBit(int r, int c, int num);
    void ClsBit(int r, int c, int num);
    void ResetFlag(int data[SD_SIZE][SD_SIZE]);
    int  GetCandidatureNum(int r, int c, int n);
    void GetSuffix(int z, int &z1, int &z2);
    void GetAllCandidature(void);
    // 消除(r,c)位置的候選數n
    void EliminateCandidature(int r, int c, int n);
    void printfResult(_Point arrDelPt[], int k, _Point pt[], int v[], int n, bool bNaked = true);
    void Merge(list<_Point> &lst1, list<_Point> & lst2, list<_Point> & lstOut);
    void printfX_Wing(_Point arrDelPt[], int k, _Point pt[], int v[], int n, bool bRow);
    // 多寶魚位置合併
    bool MergeTurbot(bool isRow, _Point arr1[], _Point arr2[], _Point ptOut[]);

    // c1 的候選數列表 是否包含c2的候選數列表
    bool IsInclude(ANSudokuCell & c1, ANSudokuCell & c2);

    // 取 c1 - c2 剩餘的候選數
    int Subtract(ANSudokuCell & c1, ANSudokuCell & c2, int arrOut[]);

    // 判斷 p3, p4所在行或者列 是否僅包含cellA中某一個候選數, 如是, 通過返回值返回
    // 該候選數; 否則返回0
    int UniquePair(ANSudokuCell &cellA, _Point &p3, _Point &p4);

    // Unique Rectangle 3
    // p1和p2點作爲一個虛擬單元格, 利用顯式數集進行候選數消除,
    // 能消除候選數的位置通過 arrDelPt 輸出, 通過v輸出這個數集,
    // 返回值爲可以消除位置的個數, 如果構不成數集或者無候選數消除,返回0
    // ---p1和p2需要排除的兩個數字, 通過v傳入------------
    int UniqueSubset(_Point &p1, _Point &p2, _Point arrDelPt[13], int v[4]);

    // 取p1和p2, 共同的house, type指明 house, row or col
    int GetHouse(_Point &p1, _Point &p2, _Point arrHouse[9], int type);

    // 判斷點arrPt(個數爲n),是否屬於同一個house (box, row, col)
    int JudgeHouse(_Point arrPt[], int n);
    // 判斷A,B,C,D是否可以組成 UR5
    int UR5(_Point &ptA, _Point &ptB, _Point &ptC, _Point &ptD);
    int UR6(_Point &ptA, _Point &ptB, _Point &ptC, _Point &ptD);
    int UR7(_Point &ptA, _Point &ptB, _Point &ptC, _Point &ptD);

    int         m_cell[SD_SIZE][SD_SIZE];
    int         m_solve[SD_SIZE][SD_SIZE];

    T_MapData   m_row[SD_SIZE];
    T_MapData   m_col[SD_SIZE];
    T_MapData   m_square[SD_SIZE];
    ANSudokuCell m_anCell[9][9];
};

#endif // !defined(AFX_SUDOKU_H__A3A5F740_4435_4643_A497_C7785C94B7E7__INCLUDED_)

 

 

 

// 多寶魚位置合併
// isRow, true表示行; flase表示列合併
// arr1 和 arr2 的元素個數都爲2; ptOut 輸出數組, 個數爲4(下標0,1爲底部)
bool Sudoku::MergeTurbot(bool isRow, _Point arr1[], _Point arr2[], _Point ptOut[])
{
    if (isRow)
    {
        if (arr1[0].c > arr1[1].c)
            swap(arr1[0], arr1[1]);
       
        if (arr2[0].c > arr2[1].c)
            swap(arr2[0], arr2[1]);
       
        if (arr1[0].c == arr2[0].c && arr1[1].c != arr2[1].c)
        {
            ptOut[0] = arr1[0];
            ptOut[1] = arr2[0];
            ptOut[2] = arr1[1];
            ptOut[3] = arr2[1];
            return true;
        }
       
        if (arr1[0].c != arr2[0].c && arr1[1].c == arr2[1].c)
        {
            ptOut[0] = arr1[1];
            ptOut[1] = arr2[1];
            ptOut[2] = arr1[0];
            ptOut[3] = arr2[0];
            return true;
        }
    }
    else // 列 合併
    {
        if (arr1[0].r > arr1[1].r)
            swap(arr1[0], arr1[1]);
       
        if (arr2[0].r > arr2[1].r)
            swap(arr2[0], arr2[1]);
       
        if (arr1[0].r == arr2[0].r && arr1[1].r != arr2[1].r)
        {
            ptOut[0] = arr1[0];
            ptOut[1] = arr2[0];
            ptOut[2] = arr1[1];
            ptOut[3] = arr2[1];
            return true;
        }
       
        if (arr1[0].r != arr2[0].r && arr1[1].r == arr2[1].r)
        {
            ptOut[0] = arr1[1];
            ptOut[1] = arr2[1];
            ptOut[2] = arr1[0];
            ptOut[3] = arr2[0];
            return true;
        }
    }
   
    return false;
}

 

 

 

// Sudoku.cpp: implementation of the Sudoku class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Sudoku.h"
#include <algorithm>

typedef set<int>                            _Candi_Set;
typedef map<_Candi_Set, list<_Point> >      _Candi_Map;
typedef pair<_Candi_Set, list<_Point> >     _Candi_Pair;
   

struct _PosCnt {
    int r;
    int c;
    int cnt;
};

struct ANSetPoint
{
    _Candi_Set s;
    list<_Point> p;
};
typedef list<ANSetPoint>                    _Candi_List;

typedef map<int, list<_Point> >             _CandiCnt_Map;
typedef pair<int, list<_Point> >            _CandiCnt_Pair;

// 用於 X-Wing
typedef map<int, _CandiCnt_Map>             _Candi_rcP_Map;
typedef pair<int, _CandiCnt_Map>            _Candi_rcP_Pair;

typedef map<int, _Point>                    _CandiPt_Map;
typedef pair<int, _Point>                   _CandiPt_Pair;

typedef map<_Candi_Set, _Point>             _CandiSetPt_Map;
typedef pair<_Candi_Set, _Point>            _CandiSetPt_Pair;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章