Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 이젠 골드구현도 어렵네..
- 취득후기
- 01BFS
- 시뮬레이션
- 게더타운시작
- 백준코딩테스트
- 엘라스틱서치
- java
- 구현
- 우선순위큐
- YBMCOS
- spring
- 다이나믹프로그래밍
- 네트워크플로우
- 세그먼트트리
- DFS
- 다익스트라
- GatherTown
- COSPROJAVA1급
- dp
- PS
- 자바PS
- QUICKSTARTGUIDE
- COSPRO
- deque
- 완전탐색
- 백준
- BFS
- 알고리즘
- 재귀함수
Archives
- Today
- Total
공부공간
BOJ - 2234 ) 성곽 본문
https://www.acmicpc.net/problem/2234
주어진 맵에서 성곽의 크기를 구하면서 벽하나를 제거해서 합친 면적중 가장 큰 값을 찾는 문제이다.
성곽의 크기를 구할때 이미 각 면적의 합을 구하고 인접여부만 CHECK배열로 확인해 준다음
인접해있다면, 두 면적을 합친값 중 가장 큰 값을 답으로 선택한다.
다음 BFS진행시에 비트연산을 해주어야하는 신박한 문제 :)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.StringTokenizer;
public class 성곽 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int map[][] = new int[m][n];
int visit[][] = new int[m][n];
for(int i =0 ; i < m;i++ ) {
st = new StringTokenizer(br.readLine());
for(int j= 0 ; j < n ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int maxarea = -1 ; int mark = 0;
int dir[][] = {{1,0},{-1,0},{0,-1},{0,1}};
ArrayDeque<int []> dq = new ArrayDeque<>(); // 0 1 coordi 2 area
for(int i = 0 ; i < m ; i++) {
for(int j= 0 ; j < n ; j++) {
if(visit[i][j] ==0) {
mark++;
visit[i][j] = mark;
dq.add(new int[] {i,j});
while(!dq.isEmpty()) {
int [] now = dq.poll();
for(int k = 0 ; k < 4 ; k++) {
int ny = now[0] + dir[k][0];
int nx = now[1] + dir[k][1];
if(ny >=0 && nx >=0 && ny < m && nx <n) {
if(k==0 && ((map[ny][nx] & 2) !=2) && ((map[now[0]][now[1]] & 8) != 8) && visit[ny][nx]==0){
visit[ny][nx] = mark;
dq.add(new int[] {ny,nx}); //내가 남쪽 가려는방향 북쪽
} else if(k==1 && ((map[ny][nx] & 8) !=8) && ((map[now[0]][now[1]] & 2) != 2) && visit[ny][nx]==0) {
visit[ny][nx] = mark;
dq.add(new int[] {ny,nx}); // 내가 북쪽 가려는방향 남쪽
} else if(k==2 && ((map[ny][nx] & 4) !=4) && ((map[now[0]][now[1]] & 1) != 1) && visit[ny][nx]==0) {
visit[ny][nx] = mark;
dq.add(new int[] {ny,nx});
} else if(k==3 && ((map[ny][nx] & 1) !=1) && ((map[now[0]][now[1]] & 4) != 4) && visit[ny][nx]==0) {
visit[ny][nx] = mark;
dq.add(new int[] {ny,nx});
}
}
}
}
}
}
}
int cnt[] = new int[mark];
boolean check[][] = new boolean[mark][mark];
for(int i = 0 ; i < m; i++) {
for(int j = 0 ; j < n ; j++) {
cnt[visit[i][j]-1]++;
if( maxarea < cnt[visit[i][j]-1]) {
maxarea = cnt[visit[i][j]-1];
}
for(int k = 0 ;k < 4 ; k++) {
int ny = i + dir[k][0];
int nx = j + dir[k][1];
if(ny >=0 && nx >=0 && ny < m && nx <n) {
if(visit[i][j] != visit[ny][nx] && !check[visit[i][j]-1][visit[ny][nx]-1]) {
check[visit[i][j]-1][visit[ny][nx]-1] = true;
}
}
}
}
}
int removearea=-1;
for(int i = 0 ; i < mark ; i++) {
for(int j = 0 ; j < mark ; j++) {
if(check[i][j]) {
int temp = cnt[i] + cnt[j];
if( removearea < temp) {
removearea = temp;
}
}
}
}
sb.append(mark +"\n"+maxarea +"\n"+removearea);
System.out.println(sb);
}
}
'알고리즘 > 완전탐색(BFS,DFS)' 카테고리의 다른 글
BOJ - 2636 ) 치즈 (0) | 2020.05.15 |
---|---|
BOJ - 16236 ) 아기상어 (0) | 2020.05.13 |
BOJ - 10971 ) 외판원 순회2 (0) | 2020.05.07 |
BOJ - 17244 ) 아맞다우산 (0) | 2020.05.06 |
BOJ - 17836 ) 공주님을 구해라! (0) | 2020.04.29 |
Comments