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

数独是一种逻辑填充游戏,要求每行、每列和每个宫包含1至9的所有数字,由日本Nikoli公司在1986年推广。尽管源于拉丁方阵,数独在20世纪末至21世纪初通过报纸和互联网在全球范围内迅速流行。它仅依赖逻辑思维,不涉及数字运算,现已成为电子设备上的热门游戏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数独 (日语数独すうどく 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
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值