Official

E - Sinking Land Editorial by en_translator


In the discussion below, we denote by \((i,j)\) the section in the \(i\)-th row from the top and \(j\)-th column from the left, and “year \(k\)” will refer to the year \(k\) years later than now.
When a section is adjacent to the sea or a section sunk in the sea, we will simply describe it as being “adjacent to the sea.”

There are only two possible kinds of moment when section \((i,j)\) sinks into the sea:

  • \(A_{i,j}\) years passes when it is adjacent to the sea.
  • For some year \(k\geq A_{i,j}\), an adjacent section sinks to the sea so that \((i,j)\) itself becomes adjacent to the sea.

In other words, each section never sinks unless it becomes adjacent to the sea, and once it becomes so, it is immediately determined when it will sink. Specifically, if section \((i,j)\) become adjacent to the sea on year \(k\) for the first time,

  • it sinks on year \(k\) if \(A_{i,j}\leq k\);
  • it sinks on year \(A_{i,j}\) if \(A_{i,j}\geq Y\);
  • it never sinks if \(A_{i,j}\geq Y\).

Based on this fact, prepare \(Y\) sequences (not a length-\(Y\) sequence) \(Q_1\), \(Q_2\), \(\ldots\), and \(Q_Y\), where \(Q_k\) consists of sections currently adjacent to the sea that will sink in the \(k\)-th day, and update them accordingly.

First, the circumference of the island, which is initially adjacent to the sea, can be considered for convenience that they becomes adjacent to the sea on year \(0\) for. Thus, (noticing \(A_{i,j}\geq 0\),) each \((i,j)\) on the circumference (that is, \(\{(i,j)|i=1 or i=H or j=1 or j=W\} \) sinks on year \(A_{i,j}\) if \(A_{i,j}\leq Y\) and never sinks in the next \(Y\) years otherwise. Therefore, for each \((i,j)\) on the circumference, append \(A_{i,j}\) to \(Q_{A_{i,j}}\) if \(A_{i,j}\leq Y\).

Afterward, for each \(k=1,2,\ldots,Y\), perform the following operation.

  • Inspect the elements (sections) of \(Q_k\) from the beginning in order: \(Q_{k,1}, Q_{k,2},\ldots\).
  • For each of the (at most four) sections adjacent to \(Q_{k,l}\) that are not yet adjacent to the sea, i.e. that becomes adjacent \(Q_{k,l}\)to sea for the first time when \(Q_{k,l}\) sinks into the sea on year, if its altitude \(A_{i',j'}\) is not greater than \(k\), then append the section to \(Q_k\); if it is between \((k+1)\) and \(Y\) (inclusive), append it to \(Q_{A_{i',j'}}\); do nothing otherwise.

By these operations, one can enumerate the sections that sinks by year \(Y\). By sequentially subtracting them from the initial area of the island \((H\times W)\), the answers can be found.

Each section occurs at most one of \(Q_1\), \(Q_2\), \(\ldots\), \(Q_Y\) only once. Also, the operation on each section in the sequence just consists of checking if adjacent sections are already sunk in the sea and appending it to some sequence according to its altitude. Hence, the total complexity is \(O(HW)\). Under the constraints of this problem, this is fast enough. Therefore, the problem has been solved.

Sample code in C++:

#include <bits/stdc++.h>
using namespace std;

#define MAX_H 1000
#define MAX_W 1000
#define MAX_Y 100000

int main(void){
	queue<int> q[MAX_Y+1];
	int a[MAX_H][MAX_W];
	bool inland[MAX_H][MAX_W];
	int h,w,n,ans,x,y,z;

	cin>>h>>w>>n;
	ans=h*w;
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			cin>>a[i][j];
			inland[i][j]=true;
			if((i==0)||(i==h-1)||(j==0)||(j==w-1)){
				q[a[i][j]].push(w*i+j);
				inland[i][j]=false;
			}
		}
	}

	int dx[4]={0,0,-1,1};
	int dy[4]={1,-1,0,0};
	for(int i=1;i<=n;i++){
		while(!q[i].empty()){
			ans--;
			z=q[i].front();
			x=z/w,y=z%w;
			q[i].pop();
			for(int j=0;j<4;j++){
				if(((x+dx[j])>=0)&&((x+dx[j])<h)&&((y+dy[j])>=0)&&((y+dy[j])<w)){
					if(inland[x+dx[j]][y+dy[j]]){
						q[max(a[x+dx[j]][y+dy[j]],i)].push(w*(x+dx[j])+(y+dy[j]));
						inland[x+dx[j]][y+dy[j]]=false;
					}
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

posted:
last update: