POJ 2676 解数独

15 篇文章 0 订阅

这个嘛。。

以前上课的时候写过一个解数独的程序,这个题顺顺利利的就过了。

我觉得我已经很暴力了。。。可是速度还是挺快的。

思路

还是枚举每个为0的点,计算这个点可能的数字数量,从最小的一个开始枚举着填。

#include <stdio.h>
#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

#define READ freopen("acm.in","r",stdin)
#define ll long long
#define PII pair<int,int>
#define PDI pair<double,int>
#define PDD pair<double,double>
#define MPI map<int,int>::iterator 
#define fst first
#define sec second
#define MS(x,d) memset(x,d,sizeof(x))
#define INF 0x3f3f3f3f
#define ALL(x) x.begin(),x.end()
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAX 5500
#define ROOT 0,n-1,1
#define PB push_back
#define FOR(a,b,c) for(int a=b;a<c;a++)




int b[10][10];
bool flag;
int Cnt(int x,int y,bool used[])
{
    MS(used,0);
    for(int i=0;i<9;i++)
    {
        used[b[x][i]]=1;
        used[b[i][y]]=1;
    }
    
    for(int i=(x/3)*3;i<(x/3)*3+3;i++)
      for(int j=(y/3)*3;j<(y/3)*3+3;j++)
           used[b[i][j]]=1;
    
    int cnt=0;

    for(int i=1;i<=9;i++)
        if(!used[i])
            cnt++;
    return cnt;
}
int check(int &x,int &y,bool ret[])
{
    int mi=100;
    for(int i=0;i<9;i++)
    for(int j=0;j<9;j++)
    {
        if(b[i][j]!=0)
            continue;
        bool used[11];
        MS(used,0);
        int res=Cnt(i,j,used);
        if(res<mi)
        { 
            mi=res;
            x=i;
            y=j;
            for(int k=1;k<=9;k++)
                ret[k]=used[k];
        }
    }  
    if(mi==100)
        return 1;// 一个为0的都没了
    if(mi==0)
        return -1;// 有一个没办法排了
    return 0;
}
void dfs()
{
    int x,y;
    bool used[11];
    int res=check(x,y,used);
    if(res==-1)
        return ;
    if(res==1)
    {
        flag=true;
        return ;
    }
    for(int i=1;i<=9&&!flag;i++)
    {
        if(!used[i])
        {
            b[x][y]=i;
            dfs();
            if(flag)
                return ;
            b[x][y]=0;
        }
    }
}
int main()
{

   // READ;
    int n;
    scanf("%d",&n);
    while(n--)
    {
        flag=0;
        for(int i=0;i<9;i++)
        {
            char num[10];
            scanf("%s",num);
            for(int j=0;j<9;j++)
                b[i][j]=num[j]-'0';
        }
        dfs();
        
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                cout<<b[i][j];
            }
            cout<<endl;
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值