POJ 2676 数独

题目: http://poj.org/problem?id=2676

题意就是打印一个数独的其中一个答案

暴力DFS,用位运算保存行,列,3×3的状态,程序跑了800多ms


#include <stdio.h>
#include <string.h>
#define MAXN 9
#define true 1
#define false 0
inline int CellPos(int i, int j)//求所在数据对应的3*3的矩阵的位置
{
	return i / 3 * 3 + j / 3 ;
}
inline void BuildHash(int i, int j, int HashRow[], int HashCol[], int HashCell[], int map[][MAXN + 2])//保存状态
{
	HashRow[i] |= (1 << (map[i][j] - 1));//行状态
	HashCol[j] |= (1 << (map[i][j] - 1));//列状态
	HashCell[CellPos(i,j)] |= (1 << (map[i][j] - 1));//3×3矩阵的状态

}
inline int TestHash(int i, int j,int val,int HashRow[], int HashCol[], int HashCell[])//检查看看有没有冲突
{
	if((val & HashRow[i]) == 0 && (val & HashCol[j]) == 0 && (val & HashCell[CellPos(i,j)]) == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
_Bool Success;
_Bool isDebug;
void dfs(const int x, const int y, int map[][MAXN + 2], int HashRow[], int HashCol[], int HashCell[],int ans[][MAXN + 2])//深搜
{
	if(Success == true)
	{
		return;
	}
	int i;
	int q;	
	int j;
	int value;
	for(q = 1; q <= MAXN; q++)
	{
		value = (1 << (q - 1));

		if(TestHash(x, y,value, HashRow, HashCol, HashCell) == true)
		{
			for (i = x; i < MAXN; i++)
			{
				for(j = 0; j < MAXN; j++)
				{
					if( ((i > x) || (i==x && j > y)) && map[i][j] == 0)
					{
						map[x][y] = q;

						int CHashRow[MAXN + 2];
						int CHashCol[MAXN + 2];
						int CHashCell[MAXN + 2];
						memcpy(CHashRow,HashRow,sizeof(CHashRow));
						memcpy(CHashCol,HashCol,sizeof(CHashCol));
						memcpy(CHashCell,HashCell,sizeof(CHashCell));
						BuildHash(x, y, HashRow, HashCol, HashCell, map);
						ans[x][y] = q;

						dfs(i, j, map, HashRow, HashCol, HashCell, ans);
						map[x][y] = 0;
						memcpy(HashRow,CHashRow,sizeof(CHashRow));
						memcpy(HashCol,CHashCol,sizeof(CHashCol));
						memcpy(HashCell,CHashCell,sizeof(CHashCell));
						//break;
						goto here;
					}
				}
			}
here:;
	 if(i == MAXN && j == MAXN)
	 {
		 ans[x][y] = q;
		 for(i = 0; i < MAXN; i++)
		 {
			 for(j = 0; j < MAXN; j++)
			 {
				 printf("%d",ans[i][j]);
			 }

			 printf("\n");
		 }
		 Success = true;
		 return;
	 }
		}
	}
}
int main()
{
	int t;
	freopen("poj2676.in","r",stdin);
	scanf("%d",&t);
	while(t--)
	{
		isDebug = false;
		Success = false;
		int HashRow[MAXN + 2];
		int HashCol[MAXN + 2];
		int HashCell[MAXN + 2];
		int ans[MAXN + 2][MAXN + 2];
		int  map[MAXN + 2][MAXN + 2];
		int i,j;
		memset(HashCell,0,sizeof(HashCell));
		memset(HashCol,0,sizeof(HashCol));
		memset(HashRow,0,sizeof(HashRow));
		char str[MAXN + 2];
		for(i = 0; i < MAXN; i++)
		{

			scanf("%s",str);
			for(j = 0; j < MAXN; j++)
			{
				map[i][j] = str[j] - '0';	
				if(map[i][j] != 0)
				{
					BuildHash(i,j,HashRow,HashCol,HashCell,map);
				}
			}
		}
		memset(ans, 0, sizeof(ans));
		for(i = 0; i < MAXN; i++)
		{
			for(j = 0; j < MAXN; j++)
			{
				if(map[i][j] == 0)
				{
					memcpy(ans,map,sizeof(ans));
					dfs(i,j,map,HashRow,HashCol,HashCell,ans);
					goto here;
				}
			}
		}
here:;
	}
	return 0;
}





你可能感兴趣的:(POJ 2676 数独)