补充

// 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;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值