zoukankan      html  css  js  c++  java
  • Sudoku(数独)

    题目描述:都玩过这个游戏,同行同列不能出现相同的数字,同一个9格子中也不能相同的出现。

    解决:dfs+回溯

    把每行每列不能用的元素检出来,在搜索的时候看每9个格子的情况,用check函数, 用两个vis数组存放行的信息和列的信息

     

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int map[10][10];
    bool vis1[10][10],vis2[10][10];
    bool found;
    bool check(int x,int y,int val)
    {//检测每9个格子中的数是否重复
        for(int i=(x-1)/3*3+1;i<=(x-1)/3*3+3;i++)
          for(int j=(y-1)/3*3+1;j<=(y-1)/3*3+3;j++)
               if(map[i][j]==val)return false;
            return true;
    }
    void show()
    {
        for(int i=1;i<=9;i++) 
            {
              for(int j=1;j<=9;j++)printf("%d",map[i][j]);  
              printf("\n");
            }
    }
    void dfs(int x,int y)
    {
        if(found)return;
       //返回条件是x=9并且y=10
        if(x==9 && y==10){found=true; show();return; }
       //若y=10,进行下一行
        if(y==10)dfs(x+1,1);
        //下标为x,y的元素是否已经有了数字,有数字的话进行下一个,
        //没有的话填写数,并回溯
        if(map[x][y])dfs(x,y+1);
        else  
        {
            for(int i=1;i<=9;i++)
            {
                if(!vis1[x][i] && !vis2[y][i] && check(x,y,i) )
                {
                    if(y<=9)
                    {
                        vis1[x][i]=1;
                        vis2[y][i]=1;
                        map[x][y]=i;
                        dfs(x,y+1);
                        vis1[x][i]=0;
                        vis2[y][i]=0;
                        map[x][y]=0;
                    }
                }
            }   
        }
    }
    int main()
    {
        int icase;
        scanf("%d",&icase);
        while(icase--)
        {
            char c;
            found=false;
            memset(vis1,0,sizeof(vis1));
            memset(vis2,0,sizeof(vis2));
             //预处理
            for(int i=1;i<=9;i++)
            {
                getchar();
                for(int j=1;j<=9;j++)
                {
                    scanf("%c",&c);
                    map[i][j]=c-'0'; 
                    if(map[i][j])
                    {//vis1数组存放的是行中是否使用,vis2存放列中某个数是否使用
                        vis1[i][map[i][j]]=1;
                        vis2[j][map[i][j]]=1;
                    }
                }
            }
           //下标从1开始
            dfs(1,1);
        }
        system("pause");
        return 0;
    }
    

  • 相关阅读:
    :nth-child(n)选择器
    lable标签的用途
    输入框事件处理
    2D转换与3D转换的区别
    vertical-align  css属性
    linux下nginx整合php
    利用crontab定时备份nginx访问日志(也可以说是定时切分日志)
    关于nginx配置虚拟主机
    linux下nginx编译安装
    正则表达式解决结巴字符串
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2174245.html
Copyright © 2011-2022 走看看