P1784 数独

题目描述

数独是根据 9 × 9 9 \times 9 9×9 盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含 1 − 9 1 - 9 19 ,不重复。每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。
芬兰一位数学家号称设计出全球最难的“数独游戏”,并刊登在报纸上,让大家去挑战。
这位数学家说,他相信只有“智慧最顶尖”的人才有可能破解这个“数独之谜”。
据介绍,目前数独游戏的难度的等级有一到五级,一是入门等级,五则比较难。不过这位数学家说,他所设计的数独游戏难度等级是十一,可以说是所以数独游戏中,难度最高的等级。他还表示,他目前还没遇到解不出来的数独游戏,因此他认为“最具挑战性”的数独游戏并没有出现。

输入格式

一个未填的数独。

输出格式

填好的数独。

思路

我们使用dfs,然后进行剪枝,因为我们可以认为有且仅有一个解,所以一旦找到解即可退出,还有,我们想想自己做数独(尽管并没有做出来)的时候,尽量选择最少的来进行尝试,所以我们可以选择最小可能值的个数的点进行尝试,具体使用状压(2进制9位记录是否可以尝试的数字)
code:

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a[10],b[10],c[10],d[10]={1,2,4,8,16,32,64,128,256,0};
int f[9][9],s,op[512],r[512];
bool o;
void dfs(int xx)
{
 if (o==1) return;
 if (xx==s)
 {
  o=1;
  return;
 }
 int x,y,z=10;
 for (int i=0;i<9;i++) for (int j=0;j<9;j++)
 {
  if (f[i][j]==-1&&op[a[i]&b[j]&c[i/3*3+j/3]]<=z)
  {
   z=op[a[i]&b[j]&c[i/3*3+j/3]];
   if (z==0)
   {
    return;
   }
   x=i,y=j;
  }
 }
 for (int k=a[x]&b[y]&c[x/3*3+y/3];k;k-=k&-k)
 {
  f[x][y]=r[k&-k];
  a[x]^=d[f[x][y]],b[y]^=d[f[x][y]],c[x/3*3+y/3]^=d[f[x][y]];
  dfs(xx+1);
  if (o==1) return;
  a[x]^=d[f[x][y]],b[y]^=d[f[x][y]],c[x/3*3+y/3]^=d[f[x][y]];
 }
 f[x][y]=-1;
 return;
}
int main()
{ for (int i=0;i<9;i++) r[d[i]]=i;
 for (int i=0;i<512;i++)
 {
  int i2=i;
  for (;i2;i2-=i2&-i2) op[i]++;
 }
 s=0;
 o=0;
 for (int i=0;i<9;i++) a[i]=b[i]=c[i]=511;
 for (int i=0;i<9;i++) for (int j=0;j<9;j++)
 {
  cin>>f[i][j];
  f[i][j]-=1;
  a[i]^=d[f[i][j]],b[j]^=d[f[i][j]],c[i/3*3+j/3]^=d[f[i][j]];
  if (f[i][j]<0) s++;
 }
 dfs(0);
 for (int i=0;i<9;i++)
 {
  for (int j=0;j<9;j++) cout<<f[i][j]+1<<' ';
  cout<<endl;
 }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值