数独 (日语:数独/すうどく 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 0
0 8 2 4 0 0 0 0 0
1 9 0 0 6 3 0 0 0
0 5 0 0 8 0 7 0 0
6 7 8 2 0 9 1 4 3
0 0 3 0 4 0 0 8 0
0 0 0 6 2 0 0 9 4
0 0 0 0 0 5 6 1 0
0 0 6 0 0 0 0 0 0
*/
/*
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
*/