Sicily 1162. Sudoku

1162. Sudoku

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with
decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task.

Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty
it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127 

#include <iostream>
#include <vector>
#include <string.h>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;

//数独题,深搜,这是剪枝的

char ans[10][10];//用来储存最终答案
bool num_in_row[10][10], num_in_col[10][10], num_in_blo[10][10];//这里的数组[i][j]表示在第i行/列/块里面已经有了j这个数字(有的时候为true)
bool is_ok;//是否找到了答案
int blank_num;//空白的数目

struct Blank {
    int pos_row, pos_col, pos_blo, possibility;//其中的possibility就是表示可能的数字的个数
}blank[85];

int find_block(int x, int y) {//返回属于的块编号

    int block[10][10] =
    {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
    0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
    0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
    0, 4, 4, 4, 5, 5, 5, 6, 6, 6,
    0, 4, 4, 4, 5, 5, 5, 6, 6, 6,
    0, 4, 4, 4, 5, 5, 5, 6, 6, 6,
    0, 7, 7, 7, 8, 8, 8, 9, 9, 9,
    0, 7, 7, 7, 8, 8, 8, 9, 9, 9,
    0, 7, 7, 7, 8, 8, 8, 9, 9, 9
    };

    return block[x][y];
}

void dfs(int blank_now) {//blank_now指当前要填的空的编号

    if (is_ok == true)//找到答案了就返回
        return;
    if (blank_now == blank_num) {//如果blank_now超过了总的空白数,也就是说空白都填完了那就返回
        is_ok = true;
        return;
    }

    for (int possible = 1; possible <= 9; possible++) {//在一个空上有9种可能

        if (!num_in_row[blank[blank_now].pos_row][possible] && !num_in_col[blank[blank_now].pos_col][possible] && !num_in_blo[blank[blank_now].pos_blo][possible]) {

            ans[blank[blank_now].pos_row][blank[blank_now].pos_col] = possible + '0';//先填入答案中,就算不对,后来填的也可以覆盖

            num_in_row[blank[blank_now].pos_row][possible] = true;//并更新这个空白的限制信息
            num_in_col[blank[blank_now].pos_col][possible] = true;
            num_in_blo[blank[blank_now].pos_blo][possible] = true;

            dfs(blank_now + 1);//深搜

            if (is_ok)//找到答案直接返回完事
                return;

            num_in_row[blank[blank_now].pos_row][possible] = false;//程序运行到这说明前面的假设没找到答案,因此还原这个空白的限制信息
            num_in_col[blank[blank_now].pos_col][possible] = false;
            num_in_blo[blank[blank_now].pos_blo][possible] = false;
        }
    }
}

void set_blank(int k, int i, int j) {

    blank[k].possibility = 0;
    blank[k].pos_row = i;
    blank[k].pos_col = j;
    blank[k].pos_blo = find_block(i, j);
}

void calculate(int k) {//这里是计算可能的数的个数
    for (int temp = 1; temp <= 9; temp++) {
        if (!num_in_row[blank[k].pos_row][temp] && !num_in_col[blank[k].pos_col][temp] && !num_in_blo[blank[k].pos_blo][temp]) {
            blank[k].possibility++;
        }
    }
}

bool cmp(const Blank &a, const Blank &b) {//按照从小到大的顺序排序
    return a.possibility < b.possibility;
}

int main() {

    int case_num, i, j;
    scanf("%d", &case_num);

    while (case_num--) {

        blank_num = 0;
        is_ok = false;
        memset(num_in_row, false, sizeof(num_in_row));
        memset(num_in_col, false, sizeof(num_in_col));
        memset(num_in_blo, false, sizeof(num_in_blo));

        for (i = 1; i <= 9; i++) {
            scanf("%s", ans[i] + 1);
        }

        for (i = 1; i <= 9; i++) {
            for (j = 1; j <= 9; j++) {
                if (ans[i][j] != '0') {//不是空白就更新限制信息

                    num_in_row[i][ans[i][j] - '0'] = true;//更新限制信息
                    num_in_col[j][ans[i][j] - '0'] = true;
                    num_in_blo[find_block(i, j)][ans[i][j] - '0'] = true;

                } else {

                    set_blank(blank_num, i, j);
                    blank_num++;

                }
            }
        }

        for (i = 0; i < blank_num; i++) {//计算possibility
            calculate(i);
        }

        sort(blank, blank + blank_num, cmp);//排序,也就是剪枝

        dfs(0);

        for (i = 1; i <= 9; i++) {
            for (j = 1; j <= 9; j++) {
                printf("%c", ans[i][j]);
            }
            printf("\n");
        }

    }

    return 0;
}
时间: 2024-08-28 17:26:21

Sicily 1162. Sudoku的相关文章

Sicily 1317. Sudoku

1317. Sudoku Constraints Time Limit: 10 secs, Memory Limit: 32 MB Description Sudoku is a placement puzzle. The goal is to enter a symbol in each cell of a grid, most frequently a 9 x 9 grid made up of 3 x 3 subgrids. Each row, column and subgrid mus

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T

(转)sicily题目分类

Sicily题目分类 ·         [数据结构/图论] 1310 Right-Heavy Tree   笛卡尔树相关,复杂度O(N)或O(NlogN). ·1426 Phone List         电话号码前缀检索,trie树相关. ·1443 Printer Queue      基本队列操作. ·1149 等价表达式         判断表达式是否等价(递归求解) ·1136 山海经             n长序列里求m次区间询问的最大连续子区间和.线段树/RMQ ·1252

LeetCode37 Sudoku Solver

题目: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution. A sudoku puzzle... ...and its solution numbers marked in red.  (Hard)

*Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution. A sudoku puzzle... ...and its solution numbers marked in red. public clas

Valid Sudoku

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. A partially filled sudoku which is valid. Note:A valid Sudoku board (partially

[LeetCode]Valid Sudoku

检测数独是否合格. 思路: 填充一遍就知道是否合格. 基本暴力搜索的思想. 1 /*************************************************************************************************** 2 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. 3 The Sudoku board could be parti

POJ Sudoku 数独填数 DFS

题目链接:Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18105   Accepted: 8772   Special Judge Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Fig

Valid Sudoku leetcode

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. A partially filled sudoku which is valid. 判断九宫格的合理性(并不一定有解),只需要依次判断行.列.9个子九宫格是否