[CSP-S Simulation Test]: paintings (BFS + math)

Title Description

Small paint of $ G $ like, especially like using only black and white paint.
Painting can be abstracted into a $ r \ times c $ $ 01 $ matrix size. Small $ G $ is now a good idea of his paintings, ready to put pen to paper and began to draw. Initially all white canvas, every time he can write a four-link portion is painted black or white.
You need to tell him, in a given idea how many times he had at least need to write complete paintings.


Input Format

The first line of two positive integers $ r, c $.
The next $ r $ rows of $ c $ characters represents the target paintings.


Output Format

Output line a positive integer representing the number of write steps required minimum.


Sample

Sample input:

3 3
010
101
010

Sample output:

2


Data range and tips

$\bullet Subtask\ 1(19pts):r\times c\leqslant 15$。
$\bullet Subtask\ 2(7pts):r=1$。
$\bullet Subtask\ 3(25pts):r,c\leqslant 30$。
$\bullet Subtask\ 4(49pts):r,c\leqslant 50$。


answer

It is a rip off his face after reading the title.

First to explain the meaning of the questions, it seems a lot of people do not know what is a four Unicom.

So what is a four Unicom, we can be understood as emotional Unicom two blocks adjacent to the side, as shown below:

As another example of Unicom not four, as shown, the only fixed-point two adjacent blocks China Unicom, but not adjacent to the edge, so it is not four Unicom:

For this question, the sample in two steps is how to come out?

First of all, starting with a white:

Then we will be dyed following figure:

In the intermediate dyed white to:

A total of two-step, just right.

Let's look at how to find the answers.

When I wanted to test an idea, layer by layer contraction inside from the outside, and then I also stuck to, and did not want to die out.

Bottleneck lies in the answer to the first contraction of how the statistics, interested people can private letter to me.

一个比较显然的结论:存在一种最优方案使得每次操作的区域是上一次的子集且颜色与上一次相反。

这个仔细脑补一下就好了,下面我也给出官方题解中的证明:

记$S$为当前所有操作区域的并,$T$为接下来一步的操作区域,我们有:
$1.$与$S$有交的情况一定可以转化成$T$被$S$包含的情况。
$2.T$与$S$交集为空时,可以找一个连接$S$和$T$的集合$M$并操作$S\cup T\cup M$,并将之前的所有操作连接到更外的层以及外层的连接部分同时操作,特殊处理最外层和第二层的情况。
$3.T$被$S$包含时,$T$落在某个完整区域内时等价于情况二,否则一定连接若干个同色块,这些块可以同时处理,步数一定不会更劣。

显然我们不能直接从外面往里面缩,所以我们考虑从中间往外面扩。

枚举扩的起点,然后用如上性质往外扩,对于所有的点取最小值即可。

使用双端队列即可优化成$\Theta(n^4)$。

时间复杂度:$\Theta(n^4)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int r,c;
char ch[100];
bool Map[100][100];
int dis[100][100];
int ans=1<<30;
deque<pair<int,int> > q;
int fx[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
bool check(int u,int v){return u>=1&&u<=r&&v>=1&&v<=c;}
int main()
{
	scanf("%d%d",&r,&c);
	for(int i=1;i<=r;i++)
	{
		scanf("%s",ch+1);
		for(int j=1;j<=c;j++)
			Map[i][j]=ch[j]-'0';
	}
	for(int i=1;i<=r;i++)
		for(int j=1;j<=c;j++)
		{
			memset(dis,-1,sizeof(dis));
			int res=-1;
			dis[i][j]=0;
			q.push_back(make_pair(i,j));
			while(q.size())
			{
				pair<int,int> flag=q.front();
				q.pop_front();
				int x=flag.first;
				int y=flag.second;
				if(Map[x][y])res=max(res,dis[x][y]);
				for(int k=0,u,v;k<4;k++)
					if(check(u=x+fx[k][0],v=y+fx[k][1])&&dis[u][v]==-1)
					{
						if(Map[x][y]==Map[u][v])
						{
							dis[u][v]=dis[x][y];
							q.push_front(make_pair(u,v));
						}
						else
						{
							dis[u][v]=dis[x][y]+1;
							q.push_back(make_pair(u,v));
						}
					}
			}
			ans=min(ans,res+1);
		}
	printf("%d",ans);
	return 0;
}

rp++

Guess you like

Origin www.cnblogs.com/wzc521/p/11576167.html