zoukankan      html  css  js  c++  java
  • poj 3074,搜索枝剪

    Sudoku
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 8909   Accepted: 3196

    Description

    In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

    . 2 7 3 8 . . 1 .
    . 1 . . . 6 7 3 5
    . . . . . . . 2 9
    3 . 5 6 9 2 . 8 .
    . . . . . . . . .
    . 6 . 1 7 4 5 . 3
    6 4 . . . . . . .
    9 5 1 8 . . . 7 .
    . 8 . . 6 5 3 4 .

    Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

    Input

    The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

    Output

    For each test case, print a line representing the completed Sudoku puzzle.

    Sample Input

    .2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
    ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
    end

    Sample Output

    527389416819426735436751829375692184194538267268174593643217958951843672782965341
    416837529982465371735129468571298643293746185864351297647913852359682714128574936

    Source

     搜索枝剪,按照每个点的可选择自由度从小到达搜索
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;

    struct node{
        int x,y,cnt;
    }p[100];
    bool cmp(const node& a,const node& b){
        return a.cnt<b.cnt;
    }
    int g[9][9];
    int row[9][10];
    int col[9][10];
    int cell[9][10];

    int getId(int x,int y){
        return (x/3)*3 + y/3;
    }

    void printans(){
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                printf("%d",g[i][j]);
            }
    //    printf(" ");
        }
        printf(" ");
    }

    int flag = 1;

    int xd[90],yd[90];
    void dfs(int n,int m){
        if(n==m){
            flag = 0;
            printans();
            return;
        }
        int small = 10;
        int x,y;
        int idx;
        for(int v =n ;v<m;v++){
            int i = p[v].x, j = p[v].y;
            p[v].cnt = 0;
            for(int k=1;k<=9;k++){
                 p[v].cnt += (row[i][k]+col[j][k]+cell[getId(i,j)][k]==0);
            }
            if(p[v].cnt==0)return;
            if(p[v].cnt<small){
                  small = p[v].cnt;
                  idx = v;
                if(small==1)break;
             }
        }
        if(small==0||small==10) return;    
        swap(p[n],p[idx]);
        x = p[n].x;
        y = p[n].y;
        for(int k=1;k<=9;k++){
            if(row[x][k]+col[y][k]+cell[getId(x,y)][k]==0&&flag){
                g[x][y] = k;
                row[x][k]=col[y][k]=cell[getId(x,y)][k]=1;
                dfs(n+1,m);
                g[x][y] = 0;
                row[x][k]=col[y][k]=cell[getId(x,y)][k]=0;
            }
        }
    }

    int main(){
        char s[100];
        while(1){
            scanf("%s",s);
            if(s[0]=='e')break;
            memset(row,0,sizeof(row));
            memset(col,0,sizeof(col));
            memset(cell,0,sizeof(cell));
            int ct_zero = 0;
            for(int u=0;u<81;u++)
            {
                int i=u/9;
                int j=u%9;
                if(s[u]>'0'&&s[u]<='9')g[i][j] = s[u]-'0';
                else {
                    g[i][j] = 0;
                    p[ct_zero].x = i;
                    p[ct_zero].y = j;
                    ct_zero++;
                }
                row[i][g[i][j]]=1;
                col[j][g[i][j]]=1;
                cell[getId(i,j)][g[i][j]]=1;
            }
            for(int v = 0;v<ct_zero;v++){
                int i = p[v].x, j = p[v].y;
                p[v].cnt = 0;
                 for(int k=1;k<=9;k++){
                      p[v].cnt += (row[i][k]+col[j][k]+cell[getId(i,j)][k]==0);
                 }
             }
            sort(p,p+ct_zero,cmp);
            flag = 1;
            dfs(0,ct_zero);    
        }
        return 0;
    }
  • 相关阅读:
    系统提供的列表框的选择菜单
    symbian 下 xml 的操作总结
    在3版中实现并动态配置开机自启动
    Symbian (Read Inbox)读取收件箱的内容
    S60平台:使用外部应用程序View
    手机通讯录助手s60 第三版与 s60第五版可用 诺基亚手机
    关于静默安装需要注意的一些问题(转)
    关于自定义控件捕获 EButton1Up 事件
    javascript简单区分现代浏览器和ie6,7,8
    301、404、200、304等HTTP状态
  • 原文地址:https://www.cnblogs.com/zhjou/p/4760815.html
Copyright © 2011-2022 走看看