x

/******************************************************************************
 * 函 数 名:    X_Chain
 *              A=B-C=D 和 D=C-B=A 重复的问题,目前的处理方式,会导致链重复。
 * 功能描述:    X-Chain方法
 * 输    入:    无
 * 输    出:    无
 * 返 回 值:    无
 * 作    者:    WWW
 * 日    期:    2010年11月3日
 * 版    本:    V2.0
 * 修改记录:
 * 日  期       版本     修改人    修改摘要
 *****************************************************************************/
int Sudoku::X_Chain()
{
    for (int r = 0; r < 18; ++r) // 9 row and 9 col
    {
        _CandiCnt_Map mapCandi;     // 这里用作 候选数 与 位置信息对应表
        if(r < 9)
            GetLinks(HOUSE_ROW, r, true, 0, mapCandi);
        else
            GetLinks(HOUSE_COL, r-9, true, 0, mapCandi);

        for (_CandiCnt_Map::iterator _itCandi=mapCandi.begin(); _itCandi!=mapCandi.end(); ++_itCandi)
        {
            int nX = _itCandi->first;    // 候选数
           
            list<list<_Point> > linksI;    // 循环查找弱强链所用的容器
            list<list<_Point> > linksN;    // 向右侧查找弱强链所用的容器

            bool bLeft = true; // 为true,则向链的左侧延伸
            linksI.push_back(_itCandi->second);
            while(!linksI.empty())
            {
                // 将I 中的第一个元素移到 N 中
                linksN.splice(linksN.begin(), linksI, linksI.begin());

                list<list<_Point> > lk;
                GetWeakStrongLinks(nX, *linksN.begin(), !bLeft, lk);
                for (list<list<_Point> >::iterator ilk=lk.begin(); ilk!=lk.end(); ++ilk)
                {
                    if ( IsExist(*linksN.begin(), *ilk) ) continue;

                    _Point p; // 端点节点
                    list<_Point>::const_iterator cit;
                   
                    if(bLeft)  {
                        cit = ++linksN.begin()->begin();
                        p = * ilk->begin();
                    }
                    else {
                        cit = -- --linksN.begin()->end();
                        p = * --ilk->end();
                    }
                    _Point pt = *cit;
                    int nSize = linksN.begin()->size();
                    int nUsed = 2; // 一条链, 有两个点组成
                  
                    int arrCandi[4];
                    arrCandi[0] = nX;
                    _Point arrDelPt[20];

                    int k = 0;
                    while(k <= 0) {
                        k = GetDelPos(pt, p, arrCandi, 1, arrDelPt);
                       
                        if (nUsed+2 > nSize) break;

                        nUsed += 2;
                        if(bLeft)   ++ ++cit;
                        else        -- --cit;
                        pt = *cit;
                    }
                   
                    //if (k <=0) continue;
                   
                    list<_Point> links; // 测试后的链
                    if(bLeft) {
                        list<_Point>::const_iterator ci1 = linksN.begin()->begin();
                        copy(ci1, ++cit, inserter(links, links.begin()));
                        links.push_front(* ++ilk->begin());
                        links.push_front(* ilk->begin());
                    }
                    else {
                        list<_Point>::const_iterator ci1 = linksN.begin()->end();
                        copy(cit, ci1, inserter(links, links.begin()));
                        links.push_back(* ilk->begin());
                        links.push_back(* ++ilk->begin());
                    }
                   
                    if (k <= 0)  linksI.push_back(links);
                   
                    // 有X-Chain
                    printf("X-Chian:");
                    for (list<_Point>::const_iterator _iL=links.begin(); _iL!=links.end(); ++_iL)
                    {
                        printf("(%d,%d)", _iL->r, _iL->c);
                    }
                   
                    printf(", 候选数%d 待删除位置", nX);
                   
                    for (int i = 0; i < k; ++i)
                    {
                        printf("(%d,%d) ", arrDelPt[i].r, arrDelPt[i].c);
                    }
                    printf("/n");
                }
            }
#if 1
            // 向另一个方向查找链
            bLeft = !bLeft;

            while(!linksN.empty())
            {
                list<list<_Point> > lk;
                GetWeakStrongLinks(nX, *linksN.begin(), !bLeft, lk);
                for (list<list<_Point> >::iterator ilk=lk.begin(); ilk!=lk.end(); ++ilk)
                {
                    if ( IsExist(*linksN.begin(), *ilk) ) continue;

                    _Point p; // 端点节点
                    list<_Point>::const_iterator cit;
                   
                    if(bLeft)  {
                        cit = ++linksN.begin()->begin();
                        p = * ilk->begin();
                    }
                    else {
                        cit = -- --linksN.begin()->end();
                        p = * --ilk->end();
                    }
                    _Point pt = *cit;
                    int nSize = linksN.begin()->size();
                    int nUsed = 2; // 一条链, 有两个点组成
                  
                    int arrCandi[4];
                    arrCandi[0] = nX;
                    _Point arrDelPt[20];

                    int k = 0;
                    while(k <= 0) {
                        k = GetDelPos(pt, p, arrCandi, 1, arrDelPt);
                       
                        if (nUsed+2 > nSize) break;

                        nUsed += 2;
                        if(bLeft)   ++ ++cit;
                        else        -- --cit;
                        pt = *cit;
                    }
                   
                    //if (k <=0) continue;
                   
                    list<_Point> links; // 测试后的链
                    if(bLeft) {
                        list<_Point>::const_iterator ci1 = linksN.begin()->begin();
                        copy(ci1, ++cit, inserter(links, links.begin()));
                        links.push_front(* ++ilk->begin());
                        links.push_front(* ilk->begin());
                    }
                    else {
                        list<_Point>::const_iterator ci1 = linksN.begin()->end();
                        copy(cit, ci1, inserter(links, links.begin()));
                        links.push_back(* ilk->begin());
                        links.push_back(* ++ilk->begin());
                    }
                                       
                    if (k <= 0)  linksN.push_back(links);
                   
                    // 有X-Chain
                    printf("X-Chian:");
                    for (list<_Point>::const_iterator _iL=links.begin(); _iL!=links.end(); ++_iL)
                    {
                        printf("(%d,%d)", _iL->r, _iL->c);
                    }
                   
                    printf(", 候选数%d 待删除位置", nX);
                   
                    for (int i = 0; i < k; ++i)
                    {
                        printf("(%d,%d) ", arrDelPt[i].r, arrDelPt[i].c);
                    }
                    printf("/n");
                }

                linksN.erase(linksN.begin());
            }
#endif
        }
    }

    return 0 ;
}


// p1 和  p2 可以共同看到的数格中,存在候选数 candi(个数为n)的数格通过 arrDel
// 输出。返回值为arrDel的元素个数
int Sudoku::GetDelPos(_Point& p1, _Point& p2, int candi[9], int n, _Point arrDel[20])
{
    _Point arrOut[20];
    int num = GetInterSection(p1, p2, 20, arrOut);

    int k = 0;
    for (int i = 0; i < num; ++i)
    {
        ANSudokuCell &cTmp = m_anCell[arrOut[i].r][arrOut[i].c];
        for (int j = 0; j < cTmp.n; ++j)
        {
            for (int m = 0; m < n; ++m)
            {
                bool bValEqual = false;
                if (cTmp.candi[j] == candi[m])
                {
                    bValEqual = true;
                    arrDel[k] = arrOut[i];
                    ++k;
                    break;
                }

                if (bValEqual) break;
            }
        }
    }

    return k;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值