https://www.acmicpc.net/problem/2606

 

백준 2606번: 바이러스 (Java) - DFS & ArrayList로 그래프 구현하기


📌 문제 개요

1번 컴퓨터가 바이러스에 걸렸다.
직접 연결된 컴퓨터를 통해 감염이 퍼질 수 있다.
감염된 컴퓨터의 총 수를 구하자. (단, 1번은 감염됐지만 제외)


💡 문제 유형

  • 그래프 탐색
  • DFS(깊이 우선 탐색)
  • 인접 리스트 방식으로 그래프 구현

🧠 핵심 개념 정리

✅ 그래프(Graph)

  • 정점(Node)과 간선(Edge)으로 이루어진 자료구조
  • 이 문제에선 컴퓨터 = 정점, 연결 = 간선

✅ DFS (Depth-First Search)

  • 깊이 우선 탐색
  • 한 방향으로 계속 탐색하다가 더 이상 갈 곳이 없으면 되돌아감
  • 재귀(Recursive) 방식으로 구현 가능

✅ 인접 리스트 (Adjacency List)

  • 정점을 배열로 선언하고, 각 인덱스에 연결된 노드들을 리스트로 저장
  • 자바에서는 ArrayList<ArrayList<Integer>> 형태로 구성
 

💻 코드 설명 (Java)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {

    static int N, M;
    static boolean[] visited;
    static ArrayList<ArrayList<Integer>> graph;
    static int cnt = 0;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        N = Integer.parseInt(br.readLine());    // 컴퓨터 수
        M = Integer.parseInt(br.readLine());    // 연결 수

        visited = new boolean[N + 1];           // 방문 배열
        graph = new ArrayList<>();

        // 인접 리스트 초기화
        for (int i = 0; i <= N; i++) {
            graph.add(new ArrayList<>());
        }

        // 간선 정보 입력
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            graph.get(a).add(b);    // 양방향 연결
            graph.get(b).add(a);
        }

        DFS(1); // 1번 컴퓨터에서 시작

        System.out.println(cnt - 1); // 자기 자신 제외
    }

    // DFS 함수
    static void DFS(int V) {
        visited[V] = true;
        cnt++;

        for (int next : graph.get(V)) {
            if (!visited[next]) {
                DFS(next);
            }
        }
    }
}

🧩 코드 분석 포인트

구문설명
graph = new ArrayList<>(); 전체 그래프 초기화
graph.add(new ArrayList<>()); 각 정점에 대한 연결 리스트 초기화
DFS(int V) 깊이 우선 탐색 함수
visited[] 중복 방문 방지용 boolean 배열
cnt - 1 감염된 컴퓨터 수에서 1번 제외
 

📝 마무리 정리

  • DFS는 연결된 모든 노드를 빠짐없이 탐색하는 데 유용
  • ArrayList를 이용한 인접 리스트 구성은 메모리 효율적
  • 1번 컴퓨터를 기준으로 연결된 컴퓨터를 모두 탐색 후, 개수만 세면 해결

 

 

 

SKT 유심 사태, 유심 꼭 교체해야 할까?

최근 SKT 유심 관련 보안 문제가 이슈가 되면서 많은 사용자들이 불안해하고 있습니다. 특히 오래된 유심을 그대로 사용하는 경우, 개인정보 유출이나 보안 취약점에 노출될 수 있어 주의가 필요합니다.

※ 유심 교체를 하지 않으면?
  • 해킹·도청 등의 보안 위협 가능성 증가
  • 개인정보(통화기록, 문자 등) 유출 우려
  • 모바일 결제 등 금융 서비스 이용 시 위험성 상승
  • 추후 보안 업데이트 지원 불가

유심 교체 방법

  1. SKT 고객센터 방문
    가까운 SK텔레콤 대리점 또는 직영점 방문 후 유심 교체 요청
    (신분증 지참 필수)
  2. 온라인 신청
    T월드 홈페이지 또는 T월드 앱에서 유심 신청
    우편으로 유심 수령 후 직접 교체 가능
  3. 직접 구매 후 개통
    일반 마트, 편의점 등에서 신규 유심 구매 후 T월드에서 개통 등록

유심 교체 시 주의사항

  • 기기 변경 없이 유심만 교체하는 경우에도 본인 인증 필요
  • 기존 유심은 폐기 전에 개인정보가 저장되어 있지 않은지 확인
  • 교체 후 일부 앱의 재인증 필요 가능성 있음

이번 사태를 계기로 유심의 보안 중요성이 크게 부각되었습니다. 스마트폰 보안을 위해 주기적인 점검과 교체를 권장드립니다.

당신의 소중한 정보, 유심 하나로 지킬 수 있습니다.

안녕하세요 26년 4월 내년결혼을 앞둔 예비신랑입니다.

스드메 예약을 마치고 우리의 베뉴 용산 로얄파크컨벤션을 잘 담을 수 있는 본식 스냅업체를 찾다가, 어두운 홀에 분위기 있고 선명한 색감 그리고 인물 위주인 ‘필포토그라피’를 보게 되었습니다.

카카오톡으로 문의드렸더니 쉬는 날임에도 불구하고 친절하고 꼼꼼히 상담해주셔서 바로 대표님으로 계약했네요!

아직 11개월 남았지만 너무 기대됩니다 ! 😎

https://www.instagram.com/fill_photography?igsh=bWJheHA2Y3FkODBl

| 아파치(apache)란?

세계에서 가장 많이 쓰는 웹 서버중 하나이며, 아파치 소프트웨어 재단에서 관리하는 HTTP 웹 서버이다.

Apache는 Apache재단에서 만든 HTTP서버로 워낙 다양한 추가기능에, 구축이 쉽다는 이유 때문에 많이 쓰고 있다. 대부분의 중소기업들은 무료이기 때문에 많이 쓰인다.

 

톰캣이란(Tomcat)?

톰캣은 아파치 소프트웨어 재단의 웹 어플리케이션 서버(와스)로서, 

자바 서블릿을 실행키고 JSP코드가 포함되어 있는 웹 페이지를 만들어준다. 

 

자바 서블랫과 JSP 규격의 '참조용 구현'으로 평가되고 있는 톰캣은, 개발자들의 개방적 협력 작업의 산물로 바이너리 버전과 소스코드 버전 둘 모두를 아파치 웹 사이트에서 얻을 수 있다. 

즉, 톰캣은 웹 서버에서 넘어온 동적인 페이지를 읽어들여 프로그램을 실행하고 그 결과를 다시 html로 재구성하여 아파치에게 되돌려 준다. 

톰캣은 자체적으로 보유하고 있는 내부 웹 서버와 함께 독립적으로 사용될 수도 있지만 아파치나 넷스케이프 엔터프라이즈 서버, IIS등 다른 웹서버와 함께 사용될 수도 있다. 톰캣을 실행시키기 위해서는 JRE 1.1이상에 부합되는 자바 런타임 환경이 필요하다.

 

| 아파치(웹서버)와 톰캣(와스)의 차이점. 

What is the deference between Aphache and Tomcat ?? (aka. 아파치 != 톰캣)  

  

그동안 아파치 톰캣이 곧 아파치인줄 알았는데(ㄷㄷ) 이 둘은 엄연히 다른것이라는 사실을 깨닫고 충격(...)을 받아서 명확히 정리하기 위한 글. 

 

Apache 아파치 =  Web Server 웹서버 

먼저 아파치는 SW단체 이름이고 우리가 흔히 알고있는 아파치 서버라는 것은 이곳에서 후원 지원하는 http Web Server를 지칭하는 말이다.

즉 아파치는 Web Server 중 하나인 것!! 하도 유명해서 아파치=웹서버 처럼 익히 알고있는 것일뿐 .. (ex. DB=oracle, mysql.. 처럼.)

 

*Web server: http 요청을 처리하는 웹서버.

 

Tomcat 톰캣 = WAS 와스 

톰캣은 흔히 와스 WAS(Web application Server) 라고 한다. 와스는 웹 서버와 서블릿 컨테이너의 결합으로 다양한 역할 수행하는 서버다. 같은 아파치(sw단체)에서 만든놈이기 때문에 아파치 톰캣이다.  요 이름때매 겁나헷갈리는것... ㅜㅜ 

클라이언트 요청을 받아 요청을 처리하고 다시 클라이언트에게 응답해주는 역할하는것이 서블릿 컨테이너이다. 

아파치와 웹 서버와의 차이의 핵심은 이 컨테이너 기능(웹서버 + 서블릿 )이 가능한가 / 불가능한가이다. 

 

 

 

 

 

정리.

| 웹서버 Web Server 

 

정적인 데이터 처리하는 서버.

단순 이미지나 html파일과 같은 리소스만을 제공하는 서버는 웹서버만 사용하여 빠르고 안정적이게 활용.

 

| 와스 WAS 

: 동적인 데이터 처리하는 서버.

 

DB로 연결되어 데이터를 주고받거나 자바등을 통해 데이터 조작이 필요한 경우에는 WAS를 활용.

 

server start 시 가장 먼저 읽어들이는 내용: Web.xml 

web.xml을 기반으로 서버가 돌아가기 위해 필요한 내용 읽어들인다.

https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html

직장을 다니면서 월급만 가지고는 부족하다고 생각하시는 분 들이 요즘 너무나도 많은게 현실인데요
가장 보편적이고 쉽게 접근 할 수 있는 쿠팡 파트너스 가입 방법 알려드리겠습니다!

가입 방법

쿠팡 파트너스 사이트에 접속합니다.

https://partners.coupang.com/

 

Coupang Partners

쿠팡과 함께 수익을 창출해보세요

partners.coupang.com

여기서, 개인과 사업자를 선택하는 기준은 다음과 같습니다.

 

- 개인 회원
: 개인회원은 실명 확인만으로 간단하게 가입이 가능합니다.
: 제세공과금 등을 수입에서 공제하고 지급하여 별도의 세금 처리 절차가 없습니다.

- 사업자
: 사업자일 경우 사업자등록증 사본을 제출해야 합니다.
: 제세공과금 등을 수입에서 공제하고 지급하지 않아 별도의 세금 처리 절차가 필요합니다.

따라서, 보통 개인 회원으로 선택합니다.


그 다음으로는 본인이 쿠팡 파트너스 활동을 진행 할 사이트 주소를 적습니다.
기입한 주소 이외에 사이트에서 활동할 경우 수익 합산이 불가할 수 있습니다.

그리고 나머지 정보들을 적어줍니다.

 


사이트 정보 기입 완료 후,
추천인 코드를 적는 칸이 있습니다.

추천인 코드를 기입하면 30일간 수익률이 1% 상승하여 4%의 수익률이 됩니다.
추천인 코드를 입력한 사람과 추천인 모두에게 적용되는 혜택입니다.
얼마 안된다고 생각하실수 있지만 누적되면 굉장히 큰 금액입니다.

혹시 추천인 코드가 없다면, 제 코드를 사용해 주시면 감사하겠습니다. :)
공란으로 두셔도 가입과는 무관합니다.

- 추천인 코드 

추천인까지 마치셨다면 다음을 클릭합니다.


이제, 단순 정보 기입만이 남았습니다.
본인의 이름, 주민번호, 연락처, 입금받을 계좌 정보를 기입합니다.

계좌 인증까지 마치셨다면 다음을 클릭합니다.


 

ㄷ. 계정 생성 완료

이제 계정 생성이 완료되었습니다.
간단하지만 긴 과정 거쳐오느라 고생하셨습니다.
이제, 사이트에서 광고가 가능합니다.
그리고 쿠팡 파트너스의 승인이 완료되면 수익을 창출할 수 있습니다.

 


4. 승인 절차

쿠파스 계정 승인 절차는 이와 같습니다.

1. 계정 생성 
2. 광고 시작
3. 최종 승인: 누적 판매 금액이 15만원 이상 발생하면 채널 검토 후 최종 승인이 이루어집니다.

하지만 최종 승인에 반려된 상태에서도 수익 집계는 정상적으로 진행됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/49189#

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코드 설명

정점, 간선이 주어진 입력 배열에서 인접리스트를 만들어서
BFS 로 가장 먼 거리를 구했다.
DFS와 BFS는 많이 풀면 풀수록 다양한 개념들이 많이 나온다.
다 이해했다고 생각하지말고 계속 여러번 반복해서 풀어봐야겠다.

import java.util.*;

class Solution {
    
    static int[] visited;
    static ArrayList<ArrayList<Integer>> al;
    
    public int solution(int n, int[][] edge) {
        int answer = 0;
        
        al = new ArrayList<>();
        visited = new int[n + 1];
        
        // 정점이 6개까지 있으므로 0~6으로 선언해야되는거 주의
        for(int i = 0; i <= n; i++)
            al.add(new ArrayList<Integer>());
        
        for(int i = 0; i < edge.length; i++){
            al.get(edge[i][0]).add(edge[i][1]);
            al.get(edge[i][1]).add(edge[i][0]);
        }
        
        BFS(1);
        
        Arrays.sort(visited);
        
        int max = visited[n];
        
        for(int i = 0; i <= n; i++){
            if(max == visited[i])
                answer++;
        }
        
        return answer;
    }
    
    public static void BFS(int V){
        Queue<Integer> qu = new LinkedList<>();
        
        qu.add(1);
        visited[1] = 1;
        
        while(!qu.isEmpty()){
            int cur = qu.poll();
            
            for(int next : al.get(cur)) {
                
                if(visited[next] == 0){
                    visited[next] = visited[cur] + 1;
                    qu.add(next);
                }
            }
        }
    }
}

https://school.programmers.co.kr/learn/courses/30/lessons/12941

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코드 설명

최솟값을 만들기 위해서는 가장 큰수와 작은수를 곱해주어야 하기 때문에
문자열 A와 문자열 B를 오름차순, 내림차순으로 각각 정렬해서
같은 인덱스끼리 곱해주려고 했으나,,
Arrays.sort 함수의 내림차순 정렬이 기억이 나지않아서
편법으로 저렇게 처리했다.

자바 Int 내림차순 정렬은 이렇게 활용하면 된다. 기억하자.. ★

Integer[] arr3 = Arrays.stream(arr).boxed().toArray(Integer[]::new);
Arrays.sort(arr3, Collections.reverseOrder());
import java.util.*;

class Solution {
    public int solution(int[] A, int[] B) {
        int answer = 0;

        Arrays.sort(A);
        Arrays.sort(B);

        for (int i = 0; i < A.length; i++) {
            answer += A[i] * B[B.length - i - 1];
        }

        return answer;
    }
}

오늘 방문한 곳은
을지로 3가역에 위치한
부타이제2막!


골목길에 위치해서 찾기 좀 어려울수도 있습니당

점심시간에는 웨이팅이 있는 편이기때문에
일찍 가야되요!

매장이 좁아서
일행이 같이 오지않으면
입장을 시켜주지 않아 기다려야되는 단점이 있어요ㅠㅠ

메인메뉴는 마제소바!
목살차슈는 기본으로 추가가 되있지않기 때문에
따로 추가를 해주어야 된다고 해요!

처음 이렇게 나오는데
노른자랑 같이 비벼서 먺으면
핵존맛탱!!

밥까지 비벼먹을수있어용

히레카츠와 후토마키도 정말 맛있어요ㅠ
어느정도 웨이팅이 있긴하지만
기다려볼만한 맛

완전 강추강추!!


영업시간
월-토
11:00 - 21:00
14:30 - 17:30 브레이크타임
14:00, 20:30 라스트오더

서울 중구 충무로5길 6-1 1층

https://school.programmers.co.kr/learn/courses/30/lessons/12939

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코드 설명

1. 문자열을 split 함수로 분리
2. String 배열을 Integer 형 배열로 바꿔서 ArrayList에 추가
3. Collections.sort 함수를 활용해서 오름차순으로 정렬
4. ArrayList에서 첫번째 인덱스(최소값) , 마지막 인덱스(최대값)을 꺼내 StringBuilder에 append

import java.util.*;

class Solution {
    public String solution(String s) {
        ArrayList<Integer> al = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        
        String arr[] = s.split(" ");
        
        for(int i = 0; i < arr.length; i++){
            al.add(Integer.parseInt(arr[i]));
        }
        
        Collections.sort(al);
        
        sb = sb.append(al.get(0) + " ");
        sb = sb.append(al.get(al.size()-1));
        
        return sb.toString();
    }
}

https://school.programmers.co.kr/learn/courses/30/lessons/12981

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코드 설명

끝말잇기 규칙을 체크해야 되는 로직을 구현해야한다.
1. 마지막 사람이 말한 단어에서 마지막 문자와 현재 사람이 말한 단어의 첫번째 문자가 일치하는지 (startsWith 함수,
마지막 단어를 순서대로 꺼내기 위해서 Stack을 활용)

2. 현재 말한 사람의 단어가 이전에 중복된 적이 있는지 (HashMap)
각각의 조건을 체크해 준 후 이상이 없으면 stack과 map에 각각 push, put 해주었고,
조건이 거짓 판별이 나면 몇번 째 사람인지와 몇바퀴 돌았는지 체크해서 각각 answer 배열에 넣어주었다.

import java.util.*;
class Solution {
    public int[] solution(int n, String[] words) {
        int[] answer = new int[2];

        HashMap<String, Integer> map = new HashMap<>();
        Stack<String> stack = new Stack<>();

        for (int i = 0; i < words.length; i++) {

            if (!stack.isEmpty()) {
                String last_word = stack.peek();
                if (words[i].startsWith(last_word.substring(last_word.length() - 1, last_word.length())) 
                        && !map.containsKey(words[i])) {
                    stack.push(words[i]);
                    map.put(words[i], i % n);
                } else {
                    answer[0] = i % n + 1;
                    answer[1] = i / n + 1;
                    break;
                }
            } else {
                stack.push(words[i]);
                map.put(words[i], i % n);
            }
        }
        
        return answer;
    }
}

+ Recent posts