zoukankan      html  css  js  c++  java
  • CodeForces 516B Drazil and Tiles 其他

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990658.html

    题目传送门 - CodeForces 516B

    题意

      给出一个$n imes m$的矩形。其中有些位置已经被覆盖。

      现在让你用$1 imes 2$的小矩形来覆盖其他地方,小矩形不能重叠。

      如果有多种覆盖方案,或者无法把没被覆盖的地方全部覆盖,那么输出特殊信息。否则输出唯一的方案。

      $n,mleq 2000$

    题解

      乍一看,我还以为是经典的二分图匹配题目。但是由于$n,m$都很大,所以不行。

      注意到题意概括中第$3$行的特殊性。

      我们考虑这样一个算法:

      首先,如果原矩阵中有被四面包围的空地,那么显然无解。

      对于原矩阵中被三面包围的空地,显然只有一种方法可以填充这个空地。

      我们考虑使用一个队列,一开始加入被三面包围的空地,然后在填充的过程中,影响到了其他的空地,并加入新的待填充空地。

      在填充的过程中可以顺便判掉某些无解的情况。

      如果按照上述操作,无法把矩阵填充满,那么就是无解或者多解了。

      至于多解的情况,很显然,任何一块连通空地如果不能找到被三面包围的空地,那么显然有多种方案来填充。

      至于为什么,自己yy。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2005;
    int dx[4]={ 0, 0, 1,-1};
    int dy[4]={-1, 1, 0, 0};
    int n,m;
    char g[N][N];
    int head=0,tail=0,x[N*N],y[N*N];
    bool flag=1;
    void ckadd(int i,int j){
    	if (g[i][j]!='.')
    		return;
    	int cnt=0;
    	for (int k=0;k<4;k++)
    		if (g[i+dx[k]][j+dy[k]]=='.')
    			cnt++;
    	if (cnt==1)
    		tail++,x[tail]=i,y[tail]=j;
    	if (cnt==0)
    		flag=0;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		scanf("%s",g[i]+1);
    	for (int i=1;i<=n;i++)
    		g[i][0]=g[i][m+1]='*';
    	for (int i=1;i<=m;i++)
    		g[0][i]=g[n+1][i]='*';
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			ckadd(i,j);
    	while (head<tail&&flag){
    		head++;
    		int i=x[head],j=y[head];
    		if (g[i][j]!='.')
    			continue;
    		int cnt=0;
    		for (int k=0;k<4;k++)
    			if (g[i+dx[k]][j+dy[k]]=='.'){
    				cnt++;
    				if (k==0)
    					g[i][j]='>',g[i+dx[k]][j+dy[k]]='<';
    				if (k==1)
    					g[i][j]='<',g[i+dx[k]][j+dy[k]]='>';
    				if (k==2)
    					g[i][j]='^',g[i+dx[k]][j+dy[k]]='v';
    				if (k==3)
    					g[i][j]='v',g[i+dx[k]][j+dy[k]]='^';
    				for (int t=0;t<4;t++)
    					ckadd(i+dx[k]+dx[t],j+dy[k]+dy[t]);
    			}
    		if (cnt==0)
    			flag=0;
    	}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (g[i][j]=='.')
    				flag=0;
    	if (!flag)
    		puts("Not unique");
    	else {
    		for (int i=1;i<=n;i++,puts(""))
    			for (int j=1;j<=m;j++)
    				putchar(g[i][j]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    SpringBoot到底run了什么
    Activity生命周期
    Activities and Tasks
    Android开发指南中文版(二)Application Fundamentals
    Android开发指南中文版(三)Intents and Intent Filters
    Android开发指南中文版(一)What is Android?
    Activity的启动模式
    skydrive 中 文件夹以zip格式下载,含有中文的文件将会被改名
    装了7个虚拟机
    google reader 居然要关闭了?
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/CF516B.html
Copyright © 2011-2022 走看看