leetCode的数独题目

leetCode36, 数独检测合法性

就是看每一行每一列以及每个九宫格子是否有重复元素

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;

struct P
{
	int i;
	int j;
	bool operator<(const P&p2)const
	{
		return (i < p2.i)||(i==p2.i&&j<p2.j);
	}

};
int numQuote(int i, int j)
{
	int nr = i / 3; int pr = j / 3;
	return nr*3 + pr;
}
class Solution {
public:
	bool isValidSudoku(vector<vector<char>>& board) {
		vector<vector<int> >rtag;
		vector<vector<int> >ctag;
		//map<P, int>pInd;//方块的索引位置
		rtag.resize(board.size());
		ctag.resize(board.size());
		for (int i = 0; i < rtag.size(); ++i)
		{
			rtag[i].resize(10);
			ctag[i].resize(10);
		}
		//进行处理
		vector<vector<int> >vqote;
		vqote.resize(9);
		for (int i = 0; i < 9; ++i)vqote[i].resize(10);
		
		vector<vector<int> >ret;
		ret.resize(9);
		for (int i = 0; i < 9; ++i)ret[i].resize(9);
		for (int i = 0; i < 9; ++i)
		{
			int num;
			for (int j = 0; j < 9; ++j)
			{
				if (board[i][j] != '.')
				{
					num = board[i][j] - '0';
					ret[i][j] = num;
					rtag[i][num] +=1;
					ctag[j][num] +=1;
					int id = numQuote(i, j);
					vqote[id][num] +=1;
					if (rtag[i][num]>1 || ctag[j][num]>1 || vqote[id][num]>1)return false;
				}
			}
		}
		return true;
	}
};


/*
5 3 . . 7 . . . .
6 . . 1 9 5 . . .
. 9 8 . . . . 6 .
8 . . . 6 . . . 3
4 . . 8 . 3 . . 1
7 . . . 2 . . . 6
. 6 . . . . 2 8 .
. . . 4 1 9 . . 5
. . . . 8 . . 7 9
*/


leetCode 37解决数独

就是在合法性的基础上,通过深度搜索每次检测当前位置可以填的数字,然后搜索下一个位置,如果到某个位置不能填数了那么回溯重复搜索

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;

struct P
{
	int i;
	int j;
	bool operator<(const P&p2)const
	{
		return (i < p2.i)||(i==p2.i&&j<p2.j);
	}

};
int numQuote(int i, int j)
{
	int nr = i / 3; int pr = j / 3;
	return nr*3 + pr;
}
P addStep(P s)
{
	P r;
	if (s.j == 8) { r.j = 0; r.i = s.i + 1; }
	else {
		r.i = s.i; r.j = s.j + 1;
	}
	return r;
}
vector<vector<int> >result;
class Solution {
public:
	void solveSudoku(vector<vector<char>>& board) {
		vector<vector<int> >rtag;
		vector<vector<int> >ctag;
		//map<P, int>pInd;//方块的索引位置
		rtag.resize(board.size());
		ctag.resize(board.size());
		for (int i = 0; i < rtag.size(); ++i)
		{
			rtag[i].resize(10);
			ctag[i].resize(10);
		}
		//进行处理
		vector<vector<int> >vqote;
		vqote.resize(9);
		for (int i = 0; i < 9; ++i)vqote[i].resize(10);
		
		vector<vector<int> >ret;
		ret.resize(9);
		for (int i = 0; i < 9; ++i)ret[i].resize(9);
		//开始填数字
		result.resize(9);
		for (int i = 0; i < 9; ++i)result[i].resize(9);
		for (int i = 0; i < 9; ++i)
		{
			int num;
			for (int j = 0; j < 9; ++j)
			{
				if (board[i][j] != '.')
				{
					num = board[i][j] - '0';
					ret[i][j] = num;
					rtag[i][num] = 1;
					ctag[j][num] = 1;
					int id = numQuote(i, j);
					vqote[id][num] = 1;
				}
			}
		}

		P st; st.i = st.j = 0;
		dfs(st, board, rtag, ctag, vqote, ret);
		for (int i = 0; i < 9; ++i)
			for (int j = 0; j < 9; ++j)
				board[i][j] = result[i][j]+'0';
		return;
	}
	//表示遍历的时候当前行的和以及列的和
	void dfs(P p, vector<vector<char> >&board,vector<vector<int> > &rtag, 
		vector<vector<int> >&ctag, vector<vector<int> >vqote,vector<vector<int> >&ret)
	{
		int i, j;
		i = p.i;
		j = p.j;
		int k = numQuote(i, j);
		if (i == 9)//结束条件
		{
			result = ret;
			return;
		}
		if (board[i][j] != '.')
		{
			dfs(addStep(p), board, rtag, ctag, vqote, ret);
			return;
		}
		for (int num = 1; num <=9; ++num)
		{
			//遍历这个数字在所在行以及列
			if (board[i][j] == '.'&&rtag[i][num] == 0 && ctag[j][num] == 0 && vqote[k][num] == 0)
			{
				rtag[i][num] = 1;
				ctag[j][num] = 1;
				vqote[k][num] = 1;
				ret[i][j] = num;
				dfs(addStep(p), board, rtag, ctag, vqote,ret);
				rtag[i][num] = 0;
				ctag[j][num] = 0;
				vqote[k][num] = 0;
			}
		}
	}
};


int main()
{
	Solution s;
	vector<vector<char> > board;
	board.resize(9);
	for (int i = 0; i < 9; ++i)
	{
		board[i].resize(9);
	}
	for (int i = 0; i < 9; ++i)
	{
		for (int j = 0; j < 9; ++j)
		{
			cin >> board[i][j];
		}
	}
	s.solveSudoku(board);
	return 0;
}

/*
5 3 . . 7 . . . .
6 . . 1 9 5 . . .
. 9 8 . . . . 6 .
8 . . . 6 . . . 3
4 . . 8 . 3 . . 1
7 . . . 2 . . . 6
. 6 . . . . 2 8 .
. . . 4 1 9 . . 5
. . . . 8 . . 7 9
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值