bzoj3074(超时了!!!)

这份代码超时了,不过是我辛苦写出来的,一次纪念!!

用到了分块的思想,然后注意选最小值,还有一个就是每次update的时候你只需要一次就好了,因为所在行和列都没有那个更新的数。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int basr[90][10], basl[90][10], basg[90][10][10];
struct gridd
{
	int i, j, value, num;
	int gnum;
	bool get;
	int getvalue(int cnt)
	{
		int a = basr[cnt][i]; int b = basl[cnt][j];
		value = (a&b) ^ (a^b);
		a = (value&basg[cnt][i / 3][j / 3]);
		b = (value^basg[cnt][i / 3][j / 3]);
		value = a^b;
		return value;
	}
	int getnum()
	{
		num = 0;
		for (int i = 0; i < 9; i++)
		{
			if (((1 << i)&value) == 0)
				num++;
		}
		return num;
	}
};
gridd grid[90][90];
struct minn
{
	int i, j;
	int num;
};
minn minr[90][10];
void updater(int cnt,int i)
{
	int nn = 0;
	for (int j = 0; j < 9; j++)
	{
		if (grid[i][j].get == 1)
		{
			nn++;
			continue;
		}
		grid[i][j].getvalue(cnt);
		grid[i][j].getnum();
		if (grid[i][j].num < minr[cnt][i].num)
		{
			minr[cnt][i].num = grid[i][j].num;
			minr[cnt][i].i = i; minr[cnt][i].j = j;
		}
	}
	if (nn == 9)
		minr[cnt][i].num = 1000000000;
}
void updatel(int cnt, int j)
{
	for (int i = 0; i < 9; i++)
	{
		if (grid[i][j].get == 1)
			continue;
		grid[i][j].getvalue(cnt);
		grid[i][j].getnum();
		if (grid[i][j].num < minr[cnt][i].num)
		{
			minr[cnt][i].num = grid[i][j].num;
			minr[cnt][i].i = i; minr[cnt][i].j = j;
		}
	}
	return;
}
void updateg(int cnt, int i, int j)
{
	int i1 = (i / 3) * 3; int i2 = (i / 3 + 1) * 3;
	int j1 = (j / 3) * 3; int j2 = (j / 3 + 1) * 3;
	for (int p = i1; p < i2; p++)
	{
		if (p == i)
			continue;
		for (int q = j1; q < j2; q++)
		{
			if (q == j)
				continue;
			if (grid[p][q].get == 1)
				continue;
			grid[p][q].getvalue(cnt);
			grid[p][q].getnum();
			if (grid[p][q].num < minr[cnt][p].num)
			{
				minr[cnt][p].num = grid[p][q].num;
				minr[cnt][p].i = p; minr[cnt][p].j = q;
			}
		}
	}
	return;
}
minn getmin(int cnt)
{
	minn a = minn();
	a.num = 1000000000;
	for (int i = 0; i < 9; i++)
	{
		if (a.num>minr[cnt][i].num)
			a = minr[cnt][i];
	}
	return a;
}
bool dfs(int cnt)
{
	minn k = getmin(cnt);
	if (k.num == 0)
		return false;
	if (k.num == 1000000000)
		return true;
	int p = k.i; int q = k.j;
	grid[p][q].getvalue(cnt);
	grid[p][q].get = 1;
	for (int i = 0; i < 9; i++)
	{
		minr[cnt + 1][i] = minr[cnt][i];
		basr[cnt + 1][i] = basr[cnt][i];
		basl[cnt + 1][i] = basl[cnt][i];
	}
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
			basg[cnt + 1][i][j] = basg[cnt][i][j];
	}
	int times = 0;
	for (int i = 0; i < 9; i++)
	{
		if ((1 << i)&grid[p][q].value)
			continue;
		grid[p][q].gnum = i + 1;
		basr[cnt + 1][p] ^= (1 << i); basl[cnt + 1][q] ^= (1 << i);
		basg[cnt + 1][p / 3][q / 3] ^= (1 << i);
		if (!times){
			minr[cnt + 1][p].num = 1000000000;
			updater(cnt + 1, p);
			updatel(cnt + 1, q);
			updateg(cnt + 1, p, q);
		}
		if (dfs(cnt + 1))return true;
		basr[cnt + 1][p] ^= (1 << i); basl[cnt + 1][q] ^= (1 << i);
		basg[cnt + 1][p / 3][q / 3] ^= (1 << i);
		times++;
	}
	grid[p][q].get = 0;
	return false;
}
char s[100];
int main()
{
	while (scanf("%s", s))
	{
		if (s[0] == 'e')
			break;
		for (int i = 0; i < 9; i++)
			basr[0][i] = 0, basl[0][i] = 0;
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				basg[0][i][j] = 0;
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				int k = i * 9 + j;
				grid[i][j].i = i; grid[i][j].j = j;
				if (s[k] == '.')
				{
					grid[i][j].get = 0;
				}
				else
				{
					grid[i][j].get = 1; grid[i][j].gnum = s[k] - '0';
					basr[0][i] |= (1<<(s[k] - '0' - 1));
					basl[0][j] |= (1<<(s[k] - '0' - 1));
					basg[0][i / 3][j / 3] |=(1<< (s[k] - '0' - 1));
				}
			}
		}
		for (int i = 0; i < 9; i++)
			minr[0][i].num = 100000000;
		for (int i = 0; i < 9; i++)
			updater(0, i);
		dfs(0);
		for (int i = 0; i < 9; i++)
			for (int j = 0; j < 9; j++)
			{
			printf("%d", grid[i][j].gnum);
			}
		printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/guoshiyuan484/article/details/80650366
今日推荐