https://community.topcoder.com/stat?c=problem_statement&pm=2998&rd=5857
public int Y_MAX = 400;
public int X_MAX = 600;
boolean area[][] = null;
public int[] sortedAreas(String[] rectangles) {
area = new boolean[Y_MAX][X_MAX];
int y = 0;
int x = 0;
// ---------
// parsing
// ---------
for (String str : rectangles) {
String[] strs = str.split(" ");
int[] index = Arrays.asList(strs).stream().mapToInt(Integer::parseInt).toArray();
for (y = index[0]; y <= index[2]; y++) {
for (x = index[1]; x <= index[3]; x++) {
area[y][x] = true;
}
}
}
// ---------
// main
// ---------
List<Integer> result = new ArrayList<Integer>();
for (y = 0; y < Y_MAX; y++) {
for (x = 0; x < X_MAX; x++) {
// if found a hall.
if (!area[y][x]) {
result.add(calcHoleArea(y, x));
}
}
}
Collections.sort(result);
int[] finalResult = new int[result.size()];
for (int i = 0; i < finalResult.length; i++) {
finalResult[i] = result.get(i);
}
return finalResult;
}
Queue<CoordinatePair> q = new LinkedList<CoordinatePair>();
private int calcHoleArea(int startY, int startX) {
int y = startY;
int x = startX;
int cntArea = 0;
q.add(new CoordinatePair(y, x));
while (!q.isEmpty()) {
CoordinatePair c = q.poll();
y = c.y;
x = c.x;
if(area[y][x]) continue;
area[y][x] = true;
cntArea++;
if ((x + 1) < X_MAX && !area[y][x + 1]) {
q.add(new CoordinatePair(y, x + 1));
}
if ((x - 1) >= 0 && !area[y][x - 1]) {
q.add(new CoordinatePair(y, x - 1));
}
if ((y + 1) < Y_MAX && !area[y + 1][x]) {
q.add(new CoordinatePair(y + 1, x));
}
if ((y - 1) >= 0 && !area[y - 1][x]) {
q.add(new CoordinatePair(y - 1, x));
}
}
return cntArea;
};
class CoordinatePair {
int x;
int y;
public CoordinatePair(int y, int x) {
super();
this.y = y;
this.x = x;
}
}
http://algoexplained.blogspot.com/2016/12/grafixmask-topcoder.html
This problem can be solved by BFS or DFS. I don't see much difference, but I used BFS that uses queue data structure. One thing to consider is to find connected cells that is only in passable point.
In order to find connected cells, I used boolean 2D arrays that saves the state of each cell, and blocked cells.
In Pseudo code,
Create queue
while (Check if there is unpainted cell that is not blocked)
getArea of all neighbors
add area into linked list
end while
array = sort linked list
return array
boolean[][] fill = new boolean[400][600];
boolean[][] blocked = new boolean[400][600];
public int[] sortedAreas(String[] retangles) {
List<Integer> list = new ArrayList<Integer>();
for (int i=0; i<400; i++) {
for (int j=0; j<600; j++) {
fill[i][j] = false;
}
}
// mark retangles
markRetangles(retangles);
ArrayList<Integer> al = new ArrayList<Integer>();
LinkedList<Node> q = new LinkedList<Node>();
while (isLeft(q)) {
al.add(getArea(q));
}
Collections.sort(al);
int[] ret = new int[al.size()];
for (int i=0;i<ret.length;i++) {
ret[i] = al.get(i);
}
return ret;
}
public void markRetangles(String[] retangles) {
for (int i=0; i<400; i++) {
for (int j=0; j<600; j++) {
blocked[i][j] = false;
}
}
for (String str : retangles) {
String[] block = str.split(" ");
int[] val = new int[4];
int i = 0;
for (String idx : block) {
val[i++] = Integer.valueOf(idx);
}
for (int j=val[0]; j<=val[2]; j++) {
for (int k=val[1]; k<=val[3]; k++) {
blocked[j][k] = true;
}
}
}
}
public int getArea(LinkedList<Node> q) {
int result = 0;
while (!q.isEmpty()) {
Node top = q.removeFirst();
result++;
int[] dx = {-1,1,0,0};
int[] dy = {0,0,-1,1};
for (int k=0;k<4;k++) {
int x = top.x + dx[k];
int y = top.y + dy[k];
if (x>=0 && x <= 399 && y >=0 && y <=599 && !fill[x][y] && !blocked[x][y]) {
q.add(new Node(x,y));
fill[x][y] = true;
}
}
}
return result;
}
public boolean isLeft(LinkedList<Node> q) {
for (int i=0; i<400; i++) {
for (int j=0; j<600; j++) {
if (!fill[i][j] && !blocked[i][j]) {
q.add(new Node(i,j));
fill[i][j] = true;
return true;
}
}
}
return false;
}
class Node {
int x,y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}
http://lianghan.org/2016/07/23/2016-7-23-GrafixMask/
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
A 400 x 600 bitmap is given. A set of rectangles covers certain parts of this bitmap (the corners of rectangles have integer coordinates). You need to find all contiguous uncovered areas, including their sizes.
http://japanslargestecommercesystem.blogspot.com/2015/09/flood-fill.htmlpublic int Y_MAX = 400;
public int X_MAX = 600;
boolean area[][] = null;
public int[] sortedAreas(String[] rectangles) {
area = new boolean[Y_MAX][X_MAX];
int y = 0;
int x = 0;
// ---------
// parsing
// ---------
for (String str : rectangles) {
String[] strs = str.split(" ");
int[] index = Arrays.asList(strs).stream().mapToInt(Integer::parseInt).toArray();
for (y = index[0]; y <= index[2]; y++) {
for (x = index[1]; x <= index[3]; x++) {
area[y][x] = true;
}
}
}
// ---------
// main
// ---------
List<Integer> result = new ArrayList<Integer>();
for (y = 0; y < Y_MAX; y++) {
for (x = 0; x < X_MAX; x++) {
// if found a hall.
if (!area[y][x]) {
result.add(calcHoleArea(y, x));
}
}
}
Collections.sort(result);
int[] finalResult = new int[result.size()];
for (int i = 0; i < finalResult.length; i++) {
finalResult[i] = result.get(i);
}
return finalResult;
}
Queue<CoordinatePair> q = new LinkedList<CoordinatePair>();
private int calcHoleArea(int startY, int startX) {
int y = startY;
int x = startX;
int cntArea = 0;
q.add(new CoordinatePair(y, x));
while (!q.isEmpty()) {
CoordinatePair c = q.poll();
y = c.y;
x = c.x;
if(area[y][x]) continue;
area[y][x] = true;
cntArea++;
if ((x + 1) < X_MAX && !area[y][x + 1]) {
q.add(new CoordinatePair(y, x + 1));
}
if ((x - 1) >= 0 && !area[y][x - 1]) {
q.add(new CoordinatePair(y, x - 1));
}
if ((y + 1) < Y_MAX && !area[y + 1][x]) {
q.add(new CoordinatePair(y + 1, x));
}
if ((y - 1) >= 0 && !area[y - 1][x]) {
q.add(new CoordinatePair(y - 1, x));
}
}
return cntArea;
};
class CoordinatePair {
int x;
int y;
public CoordinatePair(int y, int x) {
super();
this.y = y;
this.x = x;
}
}
http://algoexplained.blogspot.com/2016/12/grafixmask-topcoder.html
This problem can be solved by BFS or DFS. I don't see much difference, but I used BFS that uses queue data structure. One thing to consider is to find connected cells that is only in passable point.
In order to find connected cells, I used boolean 2D arrays that saves the state of each cell, and blocked cells.
In Pseudo code,
Create queue
while (Check if there is unpainted cell that is not blocked)
getArea of all neighbors
add area into linked list
end while
array = sort linked list
return array
boolean[][] fill = new boolean[400][600];
boolean[][] blocked = new boolean[400][600];
public int[] sortedAreas(String[] retangles) {
List<Integer> list = new ArrayList<Integer>();
for (int i=0; i<400; i++) {
for (int j=0; j<600; j++) {
fill[i][j] = false;
}
}
// mark retangles
markRetangles(retangles);
ArrayList<Integer> al = new ArrayList<Integer>();
LinkedList<Node> q = new LinkedList<Node>();
while (isLeft(q)) {
al.add(getArea(q));
}
Collections.sort(al);
int[] ret = new int[al.size()];
for (int i=0;i<ret.length;i++) {
ret[i] = al.get(i);
}
return ret;
}
public void markRetangles(String[] retangles) {
for (int i=0; i<400; i++) {
for (int j=0; j<600; j++) {
blocked[i][j] = false;
}
}
for (String str : retangles) {
String[] block = str.split(" ");
int[] val = new int[4];
int i = 0;
for (String idx : block) {
val[i++] = Integer.valueOf(idx);
}
for (int j=val[0]; j<=val[2]; j++) {
for (int k=val[1]; k<=val[3]; k++) {
blocked[j][k] = true;
}
}
}
}
public int getArea(LinkedList<Node> q) {
int result = 0;
while (!q.isEmpty()) {
Node top = q.removeFirst();
result++;
int[] dx = {-1,1,0,0};
int[] dy = {0,0,-1,1};
for (int k=0;k<4;k++) {
int x = top.x + dx[k];
int y = top.y + dy[k];
if (x>=0 && x <= 399 && y >=0 && y <=599 && !fill[x][y] && !blocked[x][y]) {
q.add(new Node(x,y));
fill[x][y] = true;
}
}
}
return result;
}
public boolean isLeft(LinkedList<Node> q) {
for (int i=0; i<400; i++) {
for (int j=0; j<600; j++) {
if (!fill[i][j] && !blocked[i][j]) {
q.add(new Node(i,j));
fill[i][j] = true;
return true;
}
}
}
return false;
}
class Node {
int x,y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}
http://lianghan.org/2016/07/23/2016-7-23-GrafixMask/