CF_292_D_ Drazil and Tiles_贪心、dfs

一步两步,一步两步,一步一步似爪牙,是魔鬼的步伐。


题意:

隔壁老王又想了个题目,在一个n*m的方阵里,*表示有障碍物,.表示空白,要求用1*2的方块填满方阵,且没有方块重叠。如果无法填满或者有多重方法,输出Not unique,否则用<>、^v方式输出填满的方式。


Input

The first line contains two integers n and m (1 ≤ n, m ≤ 2000).

The following n lines describe the grid rows. Character '.' denotes an empty cell, and the character '*' denotes a cell that is occupied.

Output

If there is no solution or the solution is not unique, you should print the string "Not unique".

Otherwise you should print how to cover all empty cells with 1 × 2 tiles. Use characters "<>" to denote horizontal tiles and characters "^v" to denote vertical tiles. Refer to the sample test for the output format example.

贪心就好,从只有一种方法的点开始,用dfs遍历,一开始用粗犷的遍历法,结果超时,用dfs的话就有顺序很多。


代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 2010
int n,m;
char a[mxn][mxn];
int mx[]={0,1,0,-1},my[]={1,0,-1,0};
bool okk(int x,int y){
	if(x<0||y<0||x>=n||y>=m)	return false;
	return a[x][y]=='.';
}
void dfs(int x,int y){
	if(!okk(x,y))	return;
	int tem=0,rec;
	for(int i=0;i<4;++i)	if(okk(x+mx[i],y+my[i])){
		++tem;
		rec=i;
	}
	if(!tem)	return;
	if(tem==1){
		if(rec==0){
			a[x][y]='<';
			a[x][y+1]='>';
		}
		else if(rec==1){
			a[x][y]='^';
			a[x+1][y]='v';
		}
		else if(rec==2){
			a[x][y]='>';
			a[x][y-1]='<';
		}
		else{
			a[x][y]='v';
			a[x-1][y]='^';
		}
		for(int i=0;i<4;++i)	
			dfs(x+mx[rec]+mx[i],y+my[rec]+my[i]);
	}
}
int main(){
	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)
				dfs(i,j);
		bool ok=true;
		for(int i=0;i<n;++i){
			for(int j=0;j<m;++j)	if(a[i][j]=='.'){
				ok=false;
				break;
			}
			if(!ok)	break;
		}
		if(!ok)	puts("Not unique");
		else for(int i=0;i<n;++i)
			printf("%s\n",a[i]);
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值