2017年院赛F题 数独游戏

来源:互联网 发布:易语言qq飞车辅助源码 编辑:程序博客网 时间:2024/05/22 12:36

目录:

2017年院赛A题 Neptune'Pudding

2017年院赛B题 N个数求和

2017年院赛C题 treat

2017年院赛D题 简单加密

2017年院赛E题 守望者的逃离

2017年院赛F题 数独游戏

2017年院赛G题 忠诚

2017年院赛H题 最大异或和


题目:

Problem Description

自从2006310日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视。

数独游戏的规则是这样的:在一个9x9的方格中,你需要把数字1-9填写到空格当中,并且使方格的每一行和每一列中都包含1-9这九个数字。同时还要保证,空格中用粗线划分成93x3的方格也同时包含1-9这九个数字。比如有这样一个题,大家可以仔细观察一下,在这里面每行、每列,以及每个3x3的方格都包含1-9这九个数字。

Input

第一行输入一个整数T,代表共有T组数据,每组之间由一个空行隔开。每组测试会给你一个 9*9 的矩阵,同一行相邻的两个元素用一个空格分开。其中1-9代表该位置的已经填好的数,数字0表示需要你填的数。

Output

对于每组测试,请输出它的解,同一行相邻的两个数用一个空格分开。两组解之间要一个空行。

对于每组测试数据保证它有且只有一个解。

Sample Input

1

7 1 2 0 6 0 3 5 8

0 6 5 2 0 7 1 0 4

0 0 8 5 1 3 6 7 2

9 2 4 0 5 6 0 3 7

5 0 6 0 0 0 2 4 1

1 0 3 7 2 0 9 0 5

0 0 1 9 7 5 4 8 6

6 0 7 8 3 0 5 1 9

8 5 9 0 4 0 0 2 3

Sample Output

7 1 2 4 6 9 3 5 8

3 6 5 2 8 7 1 9 4

4 9 8 5 1 3 6 7 2

9 2 4 1 5 6 8 3 7

5 7 6 3 9 8 2 4 1

1 8 3 7 2 4 9 6 5

2 3 1 9 7 5 4 8 6

6 4 7 8 3 2 5 1 9

8 5 9 6 4 1 7 2 3


标程:

#include<iostream>#include<cstdio>#include<cstring>#include <ctime>using namespace std;const int MAX=10;char map_[MAX][MAX];int pos[MAX*9][2];bool row[MAX][MAX], list[MAX][MAX];int k;bool check(int v,int num){    int n=pos[v][0]/3*3;    int m=pos[v][1]/3*3;    for(int i=n;i<n+3;++i){        for(int j=m;j<m+3;++j){            if(map_[i][j] == num+'0')return false;        }    }    return true;}bool DFS(int v){    if(v == k){return true;}    for(int i=1;i<10;++i){        if(!row[pos[v][0]][i] && !list[pos[v][1]][i] && check(v,i)){            map_[pos[v][0]][pos[v][1]]=i+'0';            row[pos[v][0]][i]=true;            list[pos[v][1]][i]=true;            if(DFS(v+1)){return true;}            map_[pos[v][0]][pos[v][1]]='?';            row[pos[v][0]][i]=false;            list[pos[v][1]][i]=false;        }    }    return false;}void output(){    for(int i=0;i<9;++i){        cout<<map_[i][0];        for(int j=1;j<9;++j){            cout<<' '<<map_[i][j];        }        cout<<endl;    }    return;}int main(){freopen("1.in" , "r" , stdin);freopen("1.out" , "w" , stdout);int T;scanf("%d", &T); int num=0;     while(T--){k=0;memset(row,false,sizeof row);memset(list,false,sizeof list);for(int i=0;i<9;++i){for(int j=0;j<9;++j){if(!(cin>>map_[i][j]))exit(0);if(map_[i][j] == '0'){pos[k][0]=i;pos[k++][1]=j;continue;}row[i][map_[i][j]-'0']=true;list[j][map_[i][j]-'0']=true;}}DFS(0);if(num++)cout<<endl;output();    }    return 0;} 

我的代码:

#include<iostream>using namespace std;int list[10][10];bool ok(int i, int j, int k){for (int jj = 1; jj < 10; jj++)if (list[i][jj] == k)return false;for (int ii = 1; ii < 10; ii++)if (list[ii][j] == k)return false;int x = (i - 1) / 3 * 3, y = (j - 1) / 3 * 3;for (int ii = x + 1; ii <= x + 3; ii++)for (int jj = y + 1; jj <= y + 3;jj++)if (list[ii][jj] == k)return false;return true;}bool trys(int i, int j){if (j == 10){i++;j = 1;}if (i == 10)return true;if (list[i][j])return trys(i, j + 1);for (int k = 1; k < 10; k++){if (ok(i, j, k)){list[i][j] = k;if (trys(i, j + 1))return true;}}list[i][j] = 0;return false;}void out(){for (int i = 1; i < 10; i++){for (int j = 1; j < 9; j++)cout << list[i][j]<<" ";cout <<list[i][9]<< endl;}}int main(){int t;cin>>t;while(t--){for (int i = 1; i < 10; i++)for (int j = 1; j < 10; j++)cin >>list[i][j];trys(1, 1);out();cout<<endl;}return 0;}


比赛的时候我带了好多以前打印的博客,其中一篇博客HDU - 1426 Sudoku Killer里面的题目,其实就是这个题目原题。



0 0
原创粉丝点击