区域有很多实心柱子;
俯视图矩形大小为n*m;
给出n*m个实心柱子的高度;
求最大的蓄水量。
思想:
1)构造环,联通的环来包围柱子;
2)从环上的点来扩展环,所以每次应该取出环上柱子高度最低的一个点;
3)扩展,扩展的点必须加入新环,这样就层层往里推进;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
new Task().solve() ;
}
}
class Task {
InputReader in = new InputReader(System.in) ;
PrintWriter out = new PrintWriter(System.out) ;
final int VIS = -1 ;
int n , m ;
int[][] high ;
int[][] dir = {{-1,0},{0,-1},{1,0},{0,1}} ;
boolean can(int x , int y){
return 0 <= x && x < n && 0 <= y && y < m ;
}
class Node implements Comparable<Node>{
int x , y , h ;
Node(int x , int y , int h){
this.x = x ;
this.y = y ;
this.h = h ;
}
@Override
public int compareTo(Node o) {
return (h < o.h) ? -1 : ((h == o.h) ? 0 : 1);
}
}
void solve() {
m = in.nextInt() ;
n = in.nextInt() ;
high = new int[n][m] ;
Queue<Node> q = new PriorityQueue<Node>() ;
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
high[i][j] = in.nextInt() ;
if(i == 0 || i == n-1 || j == 0 || j == m-1){
q.offer(new Node(i, j, high[i][j])) ;
high[i][j] = VIS ;
}
}
}
int sum = 0 ;
while(! q.isEmpty()){
Node u = q.poll() ;
for(int i = 0 ; i < 4 ; i++){
int x = u.x + dir[i][0] ;
int y = u.y + dir[i][1] ;
if(can(x, y) && high[x][y] != VIS){
if(high[x][y] < u.h) sum += u.h - high[x][y] ;
q.offer(new Node(x, y, Math.max(u.h , high[x][y])) ) ;
high[x][y] = VIS ;
}
}
}
out.println(sum) ;
out.flush() ;
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = new StringTokenizer("");
}
private void eat(String s) {
tokenizer = new StringTokenizer(s);
}
public String nextLine() {
try {
return reader.readLine();
} catch (Exception e) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String s = nextLine();
if (s == null)
return false;
eat(s);
}
return true;
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}