일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 17087
- 6730
- 25379
- Algorithm
- 20006
- java
- 자바
- 9081
- PS
- pccp
- 23971
- 1342
- programmers
- 파이썬
- sovled.ac
- 사용자정의필터
- SWEA
- 백준
- Django
- solved.ac
- 프로그래머스
- 11688
- 15965
- PYTHON
- 2866
- 라이브러리
- 장고
- 24511
- 알고리즘
- sloved.ac
Archives
- Today
- Total
코깽이의 코딩일기
Java 백준 19538 루머 본문
반응형
백준 링크
https://www.acmicpc.net/problem/19538
19538번: 루머
예제 1 0분 : 최초 유포자($1$, $6$번 사람)가 루머를 생성한다. 1분 : $1$번 사람은 $2$, $3$번 사람에게 루머를 퍼뜨린다. $2$번 사람은 주변인 $2$명 중 $1$명이 루머를 믿고 있어 루머를 믿게 된다. $3$
www.acmicpc.net
문제

입력

출력

입출력 예시

제출한 코드
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int n;
static Node[] nodes;
static Deque<int[]> q = new ArrayDeque<>();
static class Node {
boolean check;
int time = -1;
int cnt;
List<Integer> link = new ArrayList<>();
@Override
public String toString() {
return "Node [check=" + check + ", time=" + time + ", cnt=" + cnt + ", link=" + link + "]";
}
}
public static void main(String[] args) throws Exception {
init();
run();
printAnswer();
}
private static void init() throws Exception {
n = Integer.parseInt(br.readLine());
// 사람들을 저장할 Node 타입의 배열 할당
nodes = new Node[n + 1];
for (int i = 1; i <= n; i++) {
// 초기 Node 생성
nodes[i] = new Node();
st = new StringTokenizer(br.readLine());
// 0이 아닌 경우 까지 입력받아 link에 추가
while (st.hasMoreTokens()) {
int value = Integer.parseInt(st.nextToken());
if (value == 0)
break;
nodes[i].link.add(value);
}
}
// 최초 유포자
int m = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
for (int i = 0; i < m; i++) {
int value = Integer.parseInt(st.nextToken());
// 최초 유포자의 값 수정 및 Queue에 데이터 삽입
nodes[value].check = true;
q.add(new int[] { value, 0 });
}
}
private static void run() {
// 루머가 퍼지는 로직
while (!q.isEmpty()) {
int[] cur = q.poll();
int nowNum = cur[0];
int nowTime = cur[1];
// 루머를 믿기 시작한 시간 수정
nodes[nowNum].time = nowTime;
// 주변인들 루머 전파 시도
for (int linked : nodes[nowNum].link) {
// 이미 믿고 잇는 경우 연산X
if (nodes[linked].check)
continue;
// 주변인들 중 루머를 믿는 사람 수 + 1
nodes[linked].cnt++;
// 주변인의 수
int size = nodes[linked].link.size();
// 짝수인 경우
if (size % 2 == 0 && size / 2 > nodes[linked].cnt) continue;
// 홀수인 경우
else if (size % 2 != 0 && size / 2 + 1 > nodes[linked].cnt) continue;
// 절반 이상 루머를 믿는 경우
nodes[linked].check = true;
q.add(new int[] { linked, nowTime + 1 });
}
}
}
private static void printAnswer() {
StringBuilder sb = new StringBuilder();
for (Node output : nodes) {
if (output == null)
continue;
sb.append(output.time + " ");
}
System.out.print(sb);
}
}



1. Node라는 객체 안에 모든 정보를 저장해서 문제를 해결했다.
2. 예제 입력에서 양방향 간선으로 데이터가 주어지니 따로 추가해 줄 필요는 없다.
3. 기본 루머가 퍼지는 로직은 run()안에서 이루어진다.
4. 처음 유포자를 입력 받으면서 방문처리 기능을 하는 Node 객체 안의 check값을 true로 변경해 주고 Queue에 삽입한다.
5. while문을 통해 Queue를 돌리면서 꺼내온 데이터의 time을 수정해준다.
6. 제일 먼저 cur과 양방향 간선을 이루고 잇는 node들의 cnt 값을 증가시킨다.
7. 증가된 cnt값이 해당 node의 link의 크기의 절반 이상인지 확인한다.
8. 절반을 넘는 경우에는 새롭게 Queue에 넣으면서 check 값을 true로 변경해 준다.
9. StringBuilder를 이용해서 20만 개 데이터 출력의 시간을 줄여준다.
반응형
'PS > 백준' 카테고리의 다른 글
Java 백준 9934 완전 이진 트리 (0) | 2024.04.17 |
---|---|
Java 백준 10844 쉬운 계단 수 (0) | 2024.04.15 |
Java 백준 20006 랭킹전 대기열 (0) | 2024.04.03 |
Java 백준 14923 미로 탈출 (0) | 2024.04.01 |
Java 백준 1342 행운의 문자열 (0) | 2024.02.13 |