补充

来源:互联网 发布:网上选课系统源码 编辑:程序博客网 时间:2024/05/02 04:53

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

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 车辆超速扣12分怎么办 一次超速扣12分怎么办 分扣了罚款未交怎么办 c照一次扣12分怎么办 人在外地身份证到期了怎么办 手机进水了屏幕不亮怎么办 北京一证通过期怎么办 小米6音量键进水怎么办 考驾照怕过不了怎么办 学车对车没感觉怎么办 居住证到期2个月怎么办 生育险差一个月怎么办 驾照扣了38分怎么办 新疆转入山东上学怎么办手续 驾照过日期换证怎么办 机动车被扣24分怎么办 车辆被扣24分怎么办 现在深圳牌十年老车怎么办? 护士证过期4年了怎么办 护士资格证延续注册过期了怎么办 护士资格证过期没注册怎么办 护士资格证注册时间过期怎么办 辅警体检视力不行怎么办 护士延续注册体检怀孕怎么办 护士资格证没有延续注册怎么办 申请信用卡没有座机号码怎么办 网上申请信用卡没有座机号码怎么办 我叫上门服务被骗了怎么办 上门服务被骗了3000多怎么办 微信被骗9000元怎么办 奥迪a8气囊灯亮怎么办 驾考站岗迟到了怎么办 老板欠员工工资不给怎么办 如果有一天我没头发了怎么办 苏州公积金密码忘了怎么办 科二考试第二把怎么办 科一老是记不住怎么办 科目二考试没去怎么办 网约车驾龄不到怎么办 科四预约不上怎么办 教练不退钱怎么办找谁