题解 UVA1309 【Sudoku】
时间:2021-08-11
本文章向大家介绍题解 UVA1309 【Sudoku】,主要包括题解 UVA1309 【Sudoku】使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
这道题正解是DLX,但也可以用搜索来做,可以锻炼码力,需要加几个剪枝就能过,见代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=16;
int map[1<<N],ones[1<<N],st[N][N];
char str[N][N+1],mstr[N*N+1][N][N+1];
int mst[N*N+1][N][N],mst2[N*N+1][N][N];
void draw(int x,int y,int c)
{
str[x][y]=c+'A';
for(int i=0;i<N;++i)
{
st[x][i]&=~(1<<c);
st[i][y]&=~(1<<c);
}
int xx=x/4*4,yy=y/4*4;
for(int i=0;i<4;++i)
for(int j=0;j<4;++j)
st[xx+i][yy+j]&=~(1<<c);
st[x][y]=1<<c;
}
inline int lowbit(int x)
{
return x&-x ;
}
bool dfs(int cnt)
{
if(!cnt)return 1;
int mcnt=cnt;
memcpy(mst[mcnt],st,sizeof(st));
memcpy(mstr[mcnt],str,sizeof(str));
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
if(str[i][j]=='-')
{
if(!st[i][j])
{
memcpy(st,mst[mcnt],sizeof(st));
memcpy(str,mstr[mcnt],sizeof(str));
return 0;
}
if(ones[st[i][j]]==1)
{
draw(i,j,map[st[i][j]]);
--cnt;
}
}
for(int i=0;i<N;++i)
{
int sor=0,sand=(1<<N)-1;
int drawn=0;
for(int j=0;j<N;++j)
{
int s=st[i][j];
sand&=~(sor&s);
sor|=s;
if(str[i][j]!='-')drawn|=st[i][j];
}
if(sor!=(1<<N)-1)
{
memcpy(st,mst[mcnt],sizeof(st));
memcpy(str,mstr[mcnt],sizeof(str));
return 0;
}
for(int j=sand;j;j-=lowbit(j))
{
int t=lowbit(j);
if(!(drawn&t))
{
for(int k=0;k<N;++k)
if(st[i][k]&t)
{
draw(i,k,map[t]);
cnt--;
break;
}
}
}
}
for(int i=0;i<N;++i)
{
int sor=0,sand=(1<<N)-1;
int drawn=0;
for(int j=0;j<N;++j)
{
int s=st[j][i];
sand&=~(sor&s);
sor|=s;
if(str[j][i]!='-')drawn|=st[j][i];
}
if(sor!=(1<<N)-1)
{
memcpy(st,mst[mcnt],sizeof(st));
memcpy(str,mstr[mcnt],sizeof(str));
return 0;
}
for(int j=sand;j;j-=lowbit(j))
{
int t=lowbit(j);
if(!(drawn&t))
{
for(int k=0;k<N;++k)
if(st[k][i]&t)
{
draw(k,i,map[t]);
cnt--;
break;
}
}
}
}
for(int i=0;i<N;++i)
{
int sor=0,sand=(1<<N)-1;
int drawn=0;
for(int j=0;j<N;++j)
{
int sx=i/4*4,sy=i%4*4;
int dx=j/4,dy=j%4;
int s=st[sx+dx][sy+dy];
sand&=~(sor&s);
sor|=s;
if(str[sx+dx][sy+dy]!='-')drawn|=st[sx+dx][sy+dy];
}
if(sor!=(1<<N)-1)
{
memcpy(st,mst[mcnt],sizeof(st));
memcpy(str,mstr[mcnt],sizeof(str));
return 0;
}
for(int j=sand;j;j-=lowbit(j))
{
int t=lowbit(j);
if(!(drawn&t))
{
for(int k=0;k<N;++k)
{
int sx=i/4*4,sy=i%4*4;
int dx=k/4,dy=k%4;
if(st[sx+dx][sy+dy]&t)
{
draw(sx+dx,sy+dy,map[t]);
cnt--;
break;
}
}
}
}
}
if(!cnt)return 1;
int x,y,ms=100;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
if(str[i][j]=='-'&&ones[st[i][j]]<ms)
{
ms=ones[st[i][j]];
x=i,y=j;
}
memcpy(mst2[mcnt],st,sizeof(st));
for(int i=st[x][y];i;i-=lowbit(i))
{
memcpy(st,mst2[mcnt],sizeof(st));
draw(x,y,map[lowbit(i)]);
if(dfs(cnt-1))return 1;
}
memcpy(st,mst[mcnt],sizeof(st));
memcpy(str,mstr[mcnt],sizeof(str));
return 0;
}
int main()
{
for(int i=0;i<N;++i)map[1<<i]=i;
for(int i=0;i<(1<<N);++i)ones[i]=ones[i>>1]+(i&1);
int KASE=0;
while(scanf("%s",str[0])!=EOF)
{
if(KASE++)puts("");
for(int i=1;i<N;++i)scanf("%s",str[i]);
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
st[i][j]=(1<<N)-1;
int tot=0;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
if(str[i][j]!='-')draw(i,j,str[i][j]-'A');
else ++tot;
dfs(tot);
for(int i=0;i<N;++i)printf("%s\n",str[i]);
}
return 0;
}
原文地址:https://www.cnblogs.com/wewnb/p/15130064.html
- 复杂而艰辛的重构之路--起步
- 【强烈推荐】数据库迁移利器:Migrator.Net
- 关于某道C#上机题的OO
- Android 事件处理探险
- Fluent NHibernate RC 1.0 --升级内容
- 驳“反驳老赵之“伪”递归”
- 关于今天很热的--FizzBuzzWhizz
- 了解EF CodeFirst的Migrator功能与Migrator.Net对比
- struts技术的logic标签
- 【翻译】使用Visual Studio创建Asp.Net Core MVC (一)
- 你不知道的Javascript:有趣的setTimeout
- ADO.NET 2.0 中的新增 DataSet 功能
- WinRar 4.20 – 文件扩展名欺骗(0Day)
- 黑掉ATM取款机?只需一条短信
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法