#292 (div.2) D.Drazil and Tiles

 1.题目描述:点击打开链接

2.解题思路:本题一开始迟迟没有好的思路,随后通过思考,发现应该用贪心法解决:首先应该着力填充周围只有一个空格的点,随后以它的空格为中心,再不断向外拓展,直到整个界面被填充。这样便解决了本题。

3.代码:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;

#define N 2005
char a[N][N];
typedef pair<int, int>P;
queue<P>q;
int dx[] = { -1, 0, 1, 0 };//dx,dy必须和cg一一对应
int dy[] = { 0, 1, 0, -1 };
char cg[] = "v<^>";
int n, m;
bool is_point(int x, int y)
{
	return (x >= 0 && x < n&&y >= 0 && y < m&&a[x][y] == '.');
}
int deg(int x, int y)//找(x,y)周围空格的个数,称为度数
{
	int ans = 0;
	for (int i = 0; i < 4; i++)
	{
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (is_point(nx, ny))
			ans++;
	}
	return ans;
}

int main()
{
	//freopen("test.txt", "r", stdin);
	while (scanf("%d%d", &n, &m) != EOF)
	{
		for (int i = 0; i < n; i++)
			scanf("%s", a[i]);
		for (int i = 0; i < n;i++)
		for (int j = 0; j < m; j++)
		if (is_point(i, j) && deg(i, j) == 1)//将度为1的点入队列
			q.push(P(i, j));
		while (!q.empty())//利用BFS向外填充,由于退出循环时队列为空,因此不必清空队列
		{
			P u = q.front(); q.pop();
			int x = u.first, y = u.second;
			for (int k = 0; k < 4; k++)
			{
				int nx = x + dx[k];
				int ny = y + dy[k];
				if (is_point(nx, ny))
				{
					a[x][y] = cg[k];
					a[nx][ny] = cg[k ^ 2];
					for (int l = 0; l < 4; l++)
					{
						int mx = nx + dx[l];
						int my = ny + dy[l];
						if (is_point(mx, my) && deg(mx, my) == 1)
							q.push(P(mx, my));
					}
				}
			}
		}
		int flag = 0;
		for (int i = 0; i < n; i++)//查找是否还有点没有被填充
		{
			for (int j = 0; j < m; j++)
			if (a[i][j] == '.')
			{
				flag = 1;
				break;
			}
			if (flag)break;
		}
		if (flag)printf("Not unique\n");
		else
		{
			for (int i = 0; i < n; i++, printf("\n"))
			for (int j = 0; j < m; j++)
				putchar(a[i][j]);
		}
	}
	return 0;
}

你可能感兴趣的:(图,codeforces,贪心法)