ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

YBTOJ 数独游戏

2021-09-15 08:03:11  阅读:223  来源: 互联网

标签:10 游戏 填入 int YBTOJ 九宫格 二进制 lowbit 数独


题面

image
image

题目分析:

选择一个当前可选的数最小的位置,依次填入各个可能填入的数。

考虑怎么实现:
为了快速地得到每个位置可以选择的位置,可以将当前树所在的行、列、九宫格的填入状态压入一个二进制中储存。

Code

#include<bits/stdc++.h>
using namespace std;
const int INF=1e9+7;
int cnt[10004];//cnt[i]存储每个9位二进制数i能被取几次lowbit,即当前状态i先还有几个1,即当前状态还有几个数可选 
int num[10004];//num[i]用二进制表示每一个数,lowbit(i)中i位于第几位,i代表第几个数 
//num和cnt的值事先被预处理好,不会在过程中被改变 
int tot;//表示开始时未被填入数字的格子数有多少 
int mapp[10][10];//存储每个位置所存的数字 
int a[10],b[10],c[10];//a,b,c分别存储行、列、九宫格中的每个数是否可选的状态(压成二进制表示) 
char s[82];
int f(int x,int y){return x/3*3+y/3;}//f函数可以快速得到每个点所在九宫格的编号 
int lowbit[5005];
void change(int x,int y,int v)
{	
	a[x]^=(1<<v);
	b[y]^=(1<<v);
	c[f(x,y)]^=(1<<v); 
}//把v对应的位数更改一下(这里用xor更改,因此可以完成两种修改:不可选->可选 or 可选->不可选
bool dfs(int idx)
{
	if(idx==tot+1) return true;
	int Minv=INF,x=0,y=0;
	for(int i=0;i<9;++i)																								
	{
		for(int j=0;j<9;++j)
		{
			if(mapp[i][j]!=-1) continue;	
			int state=a[i]&b[j]&c[f(i,j)];
			if(cnt[state]==0) return false;
			if(cnt[state]<Minv) Minv=cnt[state],x=i,y=j;
		}
	}
	int state=a[x]&b[y]&c[f(x,y)];
	for(;state;state-=lowbit[state])
	{
		int val=num[lowbit[state]];
		mapp[x][y]=val;
		change(x,y,val);
		if(dfs(idx+1)) return true;
		change(x,y,val);
		mapp[x][y]=-1;	
	}
	return false;
}
void work()
{
	tot=0;
	for(int i=0;i<9;++i) a[i]=b[i]=c[i]=(1<<9)-1;
	for(int i=0;i<9;++i)
	{
		for(int j=0;j<9;++j)
		{
			char ch=s[i*9+j];
			if(ch=='.') tot++,mapp[i][j]=-1;
			else mapp[i][j]=ch-'1',change(i,j,mapp[i][j]);
		}
	}
	dfs(1);
	for(int i=0;i<9;++i) 
		for(int j=0;j<9;++j)
			printf("%d",mapp[i][j]+1);
	printf("\n");	
}
int main()
{
	for(int i=0;i<(1<<9);++i) lowbit[i]=i&(-i);
	for(int i=0;i<9;++i) num[1<<i]=i; 
	for(int i=0;i<(1<<9);++i)
		for(int j=i;j;j-=lowbit[j])
			cnt[i]++;
	while(scanf("%s",s),s[0]!='e') work();
	return 0;	
}

标签:10,游戏,填入,int,YBTOJ,九宫格,二进制,lowbit,数独
来源: https://www.cnblogs.com/mint-hexagram/p/15270584.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有