xy-c

10 篇文章 0 订阅

//----------------------------------
// [11/12/2010 anning]
// 获取链 In 以首(isHead=true)或者尾为起始点的弱强(-=)链。
void Sudoku::XY_ChainGetWeakStrongLinks(list<sdLink> & In, bool isHead, list<sdLink> & Out)
{
    _Point p1, p2;  // p1, 链首; p2, 链尾
    int nX;         // 候选数
    sdLink ln;

    list<sdLink>::const_iterator cit;
   
    if (isHead) {   //              (1,3)---> (3,Z)
        cit = --In.end();
        p1.r = cit->a/9;
        p1.c = cit->a%9;
        p2.r = cit->b/9;
        p2.c = cit->b%9;
        nX = cit->y;
        ln.x = nX;
    }
    else            //   (Z,1) <--- (1,3)
    {
        cit = In.begin();
        p1.r = cit->b/9;
        p1.c = cit->b%9;
        p2.r = cit->a/9;
        p2.c = cit->a%9;
        nX = cit->x;
        ln.y = nX;
    }

    Out.clear();
   

    list<_Point> lstPt;
    list<_Point>::iterator _iLstPt;
    GetAllLinks(false, nX, p2, p1, lstPt);
    for (_iLstPt=lstPt.begin(); _iLstPt!=lstPt.end(); ++_iLstPt)
    {
        ANSudokuCell & cell = m_anCell[_iLstPt->r][_iLstPt->c];
        if (cell.n != 2) continue;
       
        ln.a = ln.b = _iLstPt->r * SD_SIZE + _iLstPt->c;
        if (isHead)
            ln.y = cell.candi[0]==nX ? cell.candi[1] : cell.candi[0];
        else
            ln.x = cell.candi[0]==nX ? cell.candi[1] : cell.candi[0];

        Out.push_back(ln);
    }
}

// (1,2) (2,3) (3,4) (4,2) (2,1) 这里只判断和首节点的1有相同候选数的位置是否可消,
// 没有判断中间的满足条件的数格,比如(2,3)(3,4)(4,2)链,有共同数字2。
// -----------------------------------------------------------------------------
// 这里没有过滤两个节点组成的XY-Chain,因为两个节点组成的XY-Chain为数对, 例如:
// (1,2)(2,1),由Naked Pair 方法消除。
bool Sudoku::XY_Chain()
{
    for (int i = 0; i < 81; ++i) // 81个数格(编号0-80)
    {
        ANSudokuCell & cell = m_anCell[i/9][i%9];
        if (cell.n != 2) continue;

        list<list<sdLink> > linksI;    // 循环查找弱强链所用的容器
        list<list<sdLink> > linksN;    // 向右侧查找弱强链所用的容器

        bool bLeft = true; // 为true,则向链的左侧延伸
        sdLink ln;
        ln.a = ln.b = i;
        ln.x = cell.candi[0];
        ln.y = cell.candi[1];
        list<sdLink> lk;
       
        lk.push_back(ln);
        linksI.push_back(lk);
        while(!linksI.empty())
        {
            // 将I 中的第一个元素移到 N 中
            linksN.splice(linksN.begin(), linksI, linksI.begin());

            list<sdLink>::const_iterator cit;
            _Point pt;
            int X;
            if(bLeft)  {
                cit = --linksN.begin()->end();
                pt.r = cit->b / 9;
                pt.c = cit->b % 9;
                X = cit->y;
            }
            else {
                cit = linksN.begin()->begin();
                pt.r = cit->a / 9;
                pt.c = cit->a % 9;
                X = cit->x;
            }
           
            XY_ChainGetWeakStrongLinks(*linksN.begin(), !bLeft, lk);
            for (list<sdLink>::iterator ilk=lk.begin(); ilk!=lk.end(); ++ilk)
            {
                if ( IsExist(*linksN.begin(), *ilk) ) continue;
               
                int arrCandi[1];
                _Point p; // 端点节点
             
                if(bLeft)  {
                    p.r = ilk->a / 9;
                    p.c = ilk->a % 9;
                    arrCandi[0] = ilk->x;
                }
                else {
                    p.r = ilk->b / 9;
                    p.c = ilk->b % 9;
                    arrCandi[0] = ilk->y;
                }

                list<sdLink> links  = *linksN.begin(); // 测试后的链
                if(bLeft)   links.push_front(*ilk);
                else        links.push_back(*ilk);

                int k = 0;
                _Point arrDelPt[20];
                if (arrCandi[0] == X)
                    k = GetDelPos(pt, p, arrCandi, 1, arrDelPt);
               
                if (k <= 0)  linksI.push_back(links);

                if (k <= 0) continue;

                printf("XY-Chian:");
                for (list<sdLink>::const_iterator _iL=links.begin(); _iL!=links.end(); ++_iL)
                {
                    printf("(%d,%d)", _iL->a / 9, _iL->a % 9);
                }
               
                printf(", Candi:%d Cells to del:", X);
               
                for (int i = 0; i < k; ++i)
                {
                    printf("(%d,%d) ", arrDelPt[i].r, arrDelPt[i].c);
                }
                printf("/n");
            }
        }

        // 向另一个方向查找链
        bLeft = !bLeft;
        while(!linksN.empty())
        {
            list<sdLink>::const_iterator cit;
            _Point pt;
            int X;
            if(bLeft)  {
                cit = --linksN.begin()->end();
                pt.r = cit->b / 9;
                pt.c = cit->b % 9;
                X = cit->y;
            }
            else {
                cit = linksN.begin()->begin();
                pt.r = cit->a / 9;
                pt.c = cit->a % 9;
                X = cit->x;
            }
           
            XY_ChainGetWeakStrongLinks(*linksN.begin(), !bLeft, lk);
            for (list<sdLink>::iterator ilk=lk.begin(); ilk!=lk.end(); ++ilk)
            {
                if ( IsExist(*linksN.begin(), *ilk) ) continue;
               
                int arrCandi[1];
                _Point p; // 端点节点
             
                if(bLeft)  {
                    p.r = ilk->a / 9;
                    p.c = ilk->a % 9;
                    arrCandi[0] = ilk->x;
                }
                else {
                    p.r = ilk->b / 9;
                    p.c = ilk->b % 9;
                    arrCandi[0] = ilk->y;
                }

                list<sdLink> links  = *linksN.begin(); // 测试后的链
                if(bLeft)   links.push_front(*ilk);
                else        links.push_back(*ilk);

                int k = 0;
                _Point arrDelPt[20];
                if (arrCandi[0] == X)
                    k = GetDelPos(pt, p, arrCandi, 1, arrDelPt);
               
                if (k <= 0)  linksN.push_back(links);

                if (k <= 0) continue;

                printf("XY-Chian:");
                for (list<sdLink>::const_iterator _iL=links.begin(); _iL!=links.end(); ++_iL)
                {
                    printf("(%d,%d)", _iL->a / 9, _iL->a % 9);
                }
               
                printf(", Candi:%d Cells to del:", X);
               
                for (int i = 0; i < k; ++i)
                {
                    printf("(%d,%d) ", arrDelPt[i].r, arrDelPt[i].c);
                }
                printf("/n");
            }
            linksN.erase(linksN.begin());
        }
    }

    return false;
}

// 链l是否包含链t
bool IsExist(list<sdLink> & l, sdLink & t)
{
    for (list<sdLink>::iterator ipt = l.begin(); ipt != l.end(); ++ipt)
        if (ipt->a==t.a && ipt->b==t.b || ipt->a==t.b && ipt->b==t.a) return true;

    return false;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值