• 数独求解程序


    翻到以前写的一个程序。贴出来
    优先推理,无法确定的情况下找分支最少的一个去猜,并把当前状态保存,以备将来回溯。
    #include <cstdio>
    #include 
    <cstring>
    #include 
    <cassert>
    #include 
    <vector>
    #include 
    <algorithm>

    using namespace std;

    struct Node
    {
        
    char str[9][10];
        
    char used[27][10];
        
    int rest;
        
    int lastx, lasty;
        
    int dup;
        Node():dup(
    0)
        
    {
        }

        
    struct Place
        
    {
            Place(
    int _x, int _y):x(_x), y(_y){}
            
    int x, y;
            
    bool operator < (const Place &o) const
            
    {
                
    return x + y * 3 < o.x + o.y * 3;
            }

        }
    ;
        vector
    < Place > validplace[27][9];
        
    bool operator < (const Node &o) const
        
    {
            
    if (rest == o.rest)
                
    return dup < o.dup;
            
    return rest < o.rest;
        }

        
    struct Index
        
    {
            Index(
    int _i, int _k, int _size):i(_i), k(_k), size(_size){}
            
    int i, k, size;
            vector
    <Node> ns;
            
    bool operator < (const Index &o) const
            
    {
                
    return size < o.size;
            }

            
    void sortnode()
            
    {
                sort(ns.begin(), ns.end());
            }

        }
    ;
        
    void buildinfo()
        
    {
            
    int i, j;
            memset(used, 
    0sizeof(used));
            rest 
    = 0;
            
    for (i = 0; i < 9; i++)
            
    {
                
    for (j = 0; j < 9; j++)
                
    {
                    
    if (str[i][j] == '0')
                        rest
    ++, str[i][j] = 0;
                    
    else
                    
    {
                        str[i][j] 
    -= '0';
                        assert(used[i][str[i][j]] 
    == 0 && used[j + 9][str[i][j]] == 0
                         
    && used[i/3 + j/3*3 + 18][str[i][j]] == 0);
                        used[i][str[i][j]] 
    = 1;
                        used[j 
    + 9][str[i][j]] = 1;
                        used[i
    /3 + j/3*3 + 18][str[i][j]] = 1;
                    }

                }

            }

            lastx 
    = lasty = -1;
        }

        
    void guess(int i, int j, int k)
        
    {
            assert(str[i][j] 
    == 0);
            str[i][j] 
    = k;
            lastx 
    = i;
            lasty 
    = j;
            assert(used[i][k] 
    == 0 && used[j + 9][k] == 0
                
    && used[i/3 + j/3*3 + 18][k] == 0);
            used[i][k] 
    = 1;
            used[j 
    + 9][k] = 1;
            used[i
    /3 + j/3*3 + 18][k] = 1;
            rest
    --;
        }

        
    void discursion()
        
    {
            
    int i, j, k;
            
    bool change;
            
    // 先进行充分的严格推理
            do
            
    {
                change 
    = false;
                
    for (i = 0; i < 27; i++)
                
    {
                    
    for (j = 0; j < 9; j++)
                        validplace[i][j].clear();
                }

                
    for (i = 0; i < 9; i++)
                
    {
                    
    for (j = 0; j < 9; j++)
                    
    {
                        
    if (str[i][j])
                            
    continue;
                        
    for (k = 1; k <= 9; k++)
                        
    {
                            
    if (used[i][k] || used[j+9][k] || used[i/3 + j/3*3 + 18][k])
                                
    continue;
                            validplace[i][k
    -1].push_back(Place(i, j));
                            validplace[j
    +9][k-1].push_back(Place(i, j));
                            validplace[i
    /3 + j/3*3 + 18][k-1].push_back(Place(i, j));
                        }

                    }

                }

                
    for (i = 0; i < 27; i++)
                
    {
                    
    for (k = 1; k <= 9; k++)
                    
    {
                        
    if (validplace[i][k - 1].size() != 1)
                            
    continue;

                        
    const Place &= validplace[i][k - 1].front();
                        guess(p.x, p.y, k);
                        change 
    = true;
    #ifdef _DEBUG
                        
    //show();
    #endif
                        
    goto End;
                    }

                }

                End:
                ;
            }
    while(change && rest);
        }

        
    void solve()
        
    {
            discursion();

            
    if (rest == 0)
                
    return;

            
    int i, k;
            
    //选择分支最少的情况优先进行猜测
            vector<Index> best;
            vector
    <Node> nextNodes;
            
    for (i = 0; i < 27; i++)
            
    {
                
    for (k = 1; k <= 9; k++)
                
    {
                    
    if (!validplace[i][k - 1].empty())
                    
    {
                        
    //Index idx(i, k, validplace[i][k - 1].size());
                        for (int t = 0; t < validplace[i][k - 1].size(); t++)
                        
    {
                            
    const Place &= validplace[i][k - 1][t];
                            Node o2(
    *this);
                            o2.guess(p.x, p.y, k);
                            o2.discursion();
                            
    //idx.ns.push_back(o2);
                            o2.dup = validplace[i][k - 1].size();
                            nextNodes.push_back(o2);
                            
    //idx.rest += o2.rest;
                        }

                        
    //idx.sortnode();
                        
    //best.push_back(idx);
                    }

                }

            }

            
    //sort(best.begin(), best.end());
            sort(nextNodes.begin(), nextNodes.end());

            
    //for (vector<Index>::iterator id = best.begin(); id != best.end(); ++id)
            for (vector<Node>::iterator nd = nextNodes.begin(); nd != nextNodes.end(); ++nd)
            
    {
                
    //for (int i = 0; i < id->size; i++)
                {
                    
    //Node &o2 = id->ns[i];
                    Node &o2 = *nd;
                    o2.solve();
                    
    if (o2.rest == 0)
                    
    {
                        
    *this = o2;
                        
    return;
                    }

                }

            }

        }

        
    void show() const
        
    {
            
    int i, j;
            printf(
    "rest %d\n", rest);
            
    for (i = 0; i < 9; i++)
            
    {
                
    for (j = 0; j < 9; j++)
                
    {
                    
    if (str[i][j])
                    
    {
                        
    if (i == lastx && j == lasty)
                            printf(
    "-%d-", str[i][j]);
                        
    else
                            printf(
    " %d ", str[i][j]);
                    }

                    
    else
                        printf(
    "   ");
                }

                printf(
    "\n");
            }

            
    //system("pause");
        }

    }
    ;

    int main()
    {
        Node n;
        
    int i, j;
    #if 0
        
    for (i = 0; i < 9; i++)
        
    {
            scanf(
    "%s", n.str[i]);
            assert(strlen(n.str[i]) 
    == 9);
            
    for (j = 0; j < 9; j++)
            
    {
                assert(n.str[i][j] 
    >= '0' && n.str[i][j] <= '9');
            }

        }

        n.buildinfo();
        n.show();
        n.discursion();
        
    if (n.rest == 0)
            n.show();
    #else
        
    char buf[9*9+1];
        
    while(scanf("%s", buf) == 1 && buf[0!= 'e')
        
    {
            
    for (i = 0; i < 9; i++)
            
    {
                
    for (j = 0; j < 9; j++)
                
    {
                    n.str[i][j] 
    = buf[i*9+j];
                    
    if (n.str[i][j] == '.')
                        n.str[i][j] 
    = '0';
                }

            }

            n.buildinfo();
            
    //n.show();
            n.solve();
            
    //n.show();
            for (i = 0; i < 9; i++)
            
    {
                
    for (j = 0; j < 9; j++)
                
    {
                    buf[i
    *9+j] = n.str[i][j] + '0';
                }

            }

            buf[
    81= 0;
            printf(
    "%s\n", buf);
        }

    #endif
        
    return 0;
    }

  • 相关阅读:
    oracle归档空间不足的问题(rman删除归档日志)
    oracle DG查看延时时间
    Convert JS object to JSON string
    转:微信公众平台开发(80) 上传下载多媒体文件
    生成带参数的二维码
    关闭微信浏览器可以使用
    微信内置浏览器的JsAPI(WeixinJSBridge续)进入全屏
    如何隐藏微信公众平台右上角按钮
    微信公众平台服务号、订阅号的相关说明选择字号:
    微信公众平台群发消息的方法及注意事项
  • 原文地址:https://www.cnblogs.com/kaikai/p/1067850.html
Copyright © 2020-2023  润新知