数独(日语:数独/すうどく sūdoku)

来源:互联网 发布:找淘宝兼职工作靠谱吗 编辑:程序博客网 时间:2024/05/22 16:54

数独 (日语:数独すうどく sūdoku)是一种逻辑性的数字填充游戏,玩家须以数字填进每一格,而每行、每列和每个宫(即3x3的大格)有齐1至9所有数字。游戏设计者会提供一部份的数字,使谜题只有一个答案。

一个已解答的数独其实是一种多了宫的限制的拉丁方阵,因为同一个数字不可能在同一行、列或宫中出现多于一次。

这种游戏只需要逻辑思维能力,与数字运算无关。虽然玩法简单,但数字排列方式却千变万化。因为数独上的数字没有运算价值,仅仅代表相互区分的不同个体,因此可以使用其他的符号比如拉丁字母、罗马字母甚至是不图形状的图案代替。

数独是由日本的游戏公司Nikoli在1986年发扬光大的,名称“数独”的意思是“一个数字”。在2005年,数独变得世界知名。

相传数独源起于拉丁方阵(Latin Square),1970年代在美国发展,改名为“数字拼图”(Number Place)、之后流传至日本并发扬光大,以数学智力游戏智力拼图游戏发表。在1984年一本游戏杂志《パズル通信ニコリ》正式把它命名为“数独”,意思是“在每一格只有一个数字”。后来一位前任香港高等法院新西兰法官高乐德(Wayne Gould)在1997年3月到日本东京旅游时,无意中发现了。他首先在英国的《泰晤士报》上发表,不久其他报纸也发表,很快便风靡全英国,之后他用了6年时间编写了电脑程式,并将它放在网站上,使这个游戏很快在全世界流行。

台湾于2005年5月由《中国时报》首度引进, 且每日连载, 亦造成很大的回响。台湾数独发展协会(Taiwan Sudoku Association,简称TSA)亦为世界解谜联盟会员。香港则是由AM730于2005年7月30日创刊时引入数独。中国大陆是在2007年2月28日正式引入数独。北京晚报智力休闲数独俱乐部(数独联盟前身)在新闻大厦举行加入世界谜题联合会的颁证仪式,成为世界谜题联合会的39个成员之一。

后来更因子独的流行衍生了许多类似的数学智力拼图游戏,例如:数和、杀手数独。

2010年代,随着电脑和智能手机的兴起,数独在个人电脑,网站和手机上也很受欢迎[6]







S:

#include<stdio.h>#include <iostream>#include <vector>#include <algorithm>#include <cstring>using namespace std;int s[9][9], r, c;bool flag = false;bool box_3(int x, int y, int v){    for(int i = 0 ; i < 9; i++)        if(s[x][i] == v || s[i][y] == v) return false;  //已存在相等行,或者相同列具有该值,该值不可用    int r = x / 3 * 3, c = y / 3 * 3;   //整数运算,退化到小方块的顶端    for(int i = 0; i < 3; i++){        for(int j = 0 ; j < 3; j++){            if(s[r + i][c + j] == v) return false;  //小方块内已经存在该值,该值不可用        }    }    return true;            //满足两项规则,该值可以返回}void print_box(){    for(int i = 0; i < 9; i++){            for(int j = 0; j < 9; j++)                printf("%d ", s[i][j]);            printf("\n");        }}void dfs(int x, int y){  if(flag) return;                   //已经成功走完输出,返回通行令为真!  if(x == 9 && y == 0) {         //上一步x = 8, y = 9已经成功走完了全程,可以输出了      flag = true;                    //方便一路返回,返回通行令      print_box();      return;  }  if(y ==  9) dfs(x + 1, 0);        //一行搜索结束,换到下一行再继续  if(s[x][y]) dfs(x , y + 1);        //本位置不为空,进到下一位再搜索  else{                                    //本位置为空    for(int i = 1; i <= 9; i++){   //从一试到九        if(box_3(x, y, i)){             //到box_3函数中进行判断是否满足条件            s[x][y] = i;                   //满足条件存入数组            dfs(x, y + 1);                //满足前面的情况下,继续下一格走            s[x][y] = 0;                   //无法在满足前面值为i的情况下走完,“悔棋”到上一步,再次归于空        }    }  }}int main(){    //int n;    //scanf("%d", &n);    //while(n--){    while(scanf("%d", &s[0][0]) != EOF){    memset(s, 0, sizeof(s));    flag = false;/*    int v;    while(scanf("%d%d%d", &r, &c, &v), r != 0 && c != 0)        s[r - 1][c - 1] = v;*/    for(r = 0; r < 9; r++)        for(c = 0; c < 9; c++){            if(r == 0 && c == 0) continue;            else{                scanf("%d", &s[r][c]);                if(s[r][c] == '?') s[r][c] = 0;            }}    dfs(0,0);    printf("\n");    }    return 0;}/*0 0 0  0 0 0  8 0 00 8 2  4 0 0  0 0 01 9 0  0 6 3  0 0 00 5 0  0 8 0  7 0 06 7 8  2 0 9  1 4 30 0 3  0 4 0  0 8 00 0 0  6 2 0  0 9 40 0 0  0 0 5  6 1 00 0 6  0 0 0  0 0 0*//*7 1 2 0 6 0 3 5 80 6 5 2 0 7 1 0 40 0 8 5 1 3 6 7 29 2 4 0 5 6 0 3 75 0 6 0 0 0 2 4 11 0 3 7 2 0 9 0 50 0 1 9 7 5 4 8 66 0 7 8 3 0 5 1 98 5 9 0 4 0 0 2 3*/

0 0