数独游戏解密

#include<iostream>
using namespace std;

struct Board
{
	int grid[9][9];
	int topX, topY;
};

Board myBoard;
//int grid[9][9];

void InitGrid(Board& board);
int PreGrid(Board& board);
bool Maybe(Board& board, int I, int J, int V);
bool sloveBoard(Board& board);

void printMessage()
{
	cout << "输入格式:\n123------\n---456---\n------789\n---------\n---------\n---------\n---------\n---------\n---------\n";
	cout << endl << "输入题目:" << endl;
}


int main()
{
	printMessage();
	InitGrid(myBoard);
	cout << endl;
	if (sloveBoard(myBoard))
	{
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)  //可以修改输出格式
			{
				cout << myBoard.grid[i][j];
				if (j % 3 == 2)
				{
					cout << "|";
				}
				else
				{
					cout << " ";
				}
			}
			cout << endl;
			if (i % 3 == 2)
			{
				cout << "--------------------" << endl;
			}
		}
	}
	else
	{
		cout << "error" << endl;
	}

	system("pause");
	return 0;
}

//返回board能否得到正确解
bool sloveBoard(Board& board)
{
	Board tmpBoard = board;
	int ans = PreGrid(tmpBoard);
	if (ans < 0)
	{
		return false;
	}
	if (ans == 1)
	{
		board = tmpBoard;
		return sloveBoard(board);
	}
	if (ans == 2)
	{
		board = tmpBoard;
		return true;
	}
	if (ans == 0)
	{
		int V = tmpBoard.grid[tmpBoard.topX][tmpBoard.topY];
		while (V > 0)
		{
			int testV = V % 10;
			V /= 10;
			Board ttBoard = tmpBoard;
			ttBoard.grid[tmpBoard.topX][tmpBoard.topY] = testV;
			if (sloveBoard(ttBoard))
			{
				board = ttBoard;
				return true;
			}
		}
		return false;
	}
	return false;
}

//读入题目
void InitGrid(Board& board)
{
	int readNum = 0;
	while (readNum < 81)
	{
		char c;
		cin >> c;
		if (c > '0' && c <= '9')
		{
			board.grid[readNum / 9][readNum % 9] = (int)(c - '0');
		}
		else if (c == '#' || c == '0') //这里的分隔符可以修改
		{
			board.grid[readNum / 9][readNum % 9] = 0;
		}
		else
		{
			continue;
		}
		readNum++;
	}
}

/*
-1:错误
0:完成预填
1:预填因出现确定格子而终止
2:没有格子可以预填(完成数独)
*/
int PreGrid(Board& board)
{
	int initDate = 1300000000;
	int minGridValue = initDate;
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			if (board.grid[i][j] > 0 && board.grid[i][j] < 10)
			{
				if (!Maybe(board, i, j, board.grid[i][j]))
					return -1;
				continue;
			}
			else
			{
				board.grid[i][j] = 0;
				for (int t = 1; t < 10; t++)
				{
					if (Maybe(board, i, j, t))
					{
						board.grid[i][j] *= 10;
						board.grid[i][j] += t;
					}
				}
				if (board.grid[i][j] > 0 && board.grid[i][j] < 10)
				{
					return 1;
				}
				else if (board.grid[i][j] <= 0)
				{
					return -1;
				}
				else
				{
					if (board.grid[i][j] < minGridValue)
					{
						minGridValue = board.grid[i][j];
						board.topX = i;
						board.topY = j;
					}
				}
			}
		}
	}
	if (minGridValue == initDate)
	{
		return 2;
	}
	else
	{
		return 0;
	}
}

//返回board中坐标(I,J)位置是否可能为值V,可能返回true,不可能返回false
bool Maybe(Board& board, int I, int J, int V)
{
	int baseX = I - I % 3;
	int baseY = J - J % 3;
	for (int s = 0; s < 9; s++)
	{
		if (s != I && board.grid[s][J] == V)
		{
			return false;
		}
		if (s != J && board.grid[I][s] == V)
		{
			return false;
		}
		int dltX = s / 3;
		int dltY = s % 3;
		if (((baseX + dltX) != I || (baseY + dltY) != J) && board.grid[baseX + dltX][baseY + dltY] == V)
		{
			return false;
		}
	}
	return true;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Automan之鸿鹄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值