其他分享
首页 > 其他分享> > 华为机试题 Sudoku

华为机试题 Sudoku

作者:互联网

简介

使用回溯算法.
其实回溯算法属于暴力算法. 进行一定的减枝算法即可.

这里要使用弱检查, 全局flag 进行退出.

code

#include <iostream>
#include <vector>
#include <set>
#include <map>
using namespace std;


void input(int a[][9], vector<pair<int, int>> &v){
    for(int i=0; i<9; i++){
        for(int j = 0; j<9; j++){
            cin >> a[i][j];
            if(a[i][j] == 0)  v.push_back({i,j});
        }
    }
}
void output(int a[][9]) {
    for(int i=0; i<9; i++){
        for(int j = 0; j<9; j++){
            if(j==0) cout << a[i][j];
            else cout << " " << a[i][j];
        }
        cout << endl;
    }
}



bool checkRow(int a[][9], int row){
    set<int> s;
    for(int j=0; j<9; j++){
        if(a[row][j] != 0)
            s.insert(a[row][j]);
    }
    if(s.size() == 9) {
        return true;
    }
    return false;
}

bool checkRowWeak(int a[][9], int row){
    set<int> s;
    int count = 0;
    for(int j=0; j<9; j++){
        if(a[row][j] != 0) {
            s.insert(a[row][j]);
            count++;
        }
    }
    if(s.size() == count) { // 无重复
        return true;
    }
    return false;
}

bool checkColWeak(int a[][9], int col){
    set<int> s;
    int count = 0;
    for(int i=0; i<9; i++){
        if(a[i][col] != 0) {
            s.insert(a[i][col]);
            count++;
        } 
    }
    if(s.size() == count) {
        return true;
    }
    return false;
}

bool checkCol(int a[][9], int col){
    set<int> s;
    for(int i=0; i<9; i++){
        if(a[i][col] != 0)
            s.insert(a[i][col]);
    }
    if(s.size() == 9) {
        return true;
    }
    return false;
}

bool checkBlock(int a[][9], int row, int col) {
    int blockRow = (row / 3) * 3;
    int blockCol = (col / 3) * 3;
    set<int> s;
    for(int i=blockRow; i<blockRow + 3; i++){
        for(int j = blockCol; j < blockCol + 3; j++){
            if(a[i][j] != 0)
                s.insert(a[i][j]);
        }
    }
    if(s.size() == 9) return true;
    return false;
}


bool checkBlockWeak(int a[][9], int row, int col) {
    int blockRow = (row / 3) * 3;
    int blockCol = (col / 3) * 3;
    int count = 0;
    set<int> s;
    for(int i=blockRow; i<blockRow + 3; i++){
        for(int j = blockCol; j < blockCol + 3; j++){
            if(a[i][j] != 0) {
                count++;
                s.insert(a[i][j]);
            }   
        }
    }
    if(s.size() == count) return true;
    return false;
}

bool check(int a[][9], int i, int j) {
    if(checkColWeak(a, j) && checkRowWeak(a, i) && checkBlockWeak(a, i, j)){
        return true;
    }
    return false;
}
bool flag = false;
void dfs(int a[][9], int index, map<pair<int, int>, bool> &vis, vector<pair<int, int>> & v) {
    if(index == v.size()){
        flag = true;
        return;
    }
    int row = v[index].first;
    int col = v[index].second;
    bool ch = false;
    for(int i=0; i<9; i++){
        a[row][col] = i+1;
        if(check(a, row, col)) {
            dfs(a,index+1,vis,v);
        }
        if(flag) break;
        a[row][col] = 0;
    }
}

int main() {
    int a[9][9] = {0};
    vector<pair<int, int>> v;
    input(a, v);
    map<pair<int, int>, bool> vis;
    dfs(a, 0, vis, v);
    output(a);
}

标签:Sudoku,试题,index,int,算法,vis,华为,bool,include
来源: https://www.cnblogs.com/eat-too-much/p/14940518.html