728x90
반응형

전화번호 목록 - 2Level

문제설명

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
    • 각 전화번호의 길이는 1 이상 20 이하입니다.
    • 같은 전화번호가 중복해서 들어있지 않습니다.

입출력 예

입출력 예 설명

입출력 예 #1
앞에서 설명한 예와 같습니다.

입출력 예 #2
한 번호가 다른 번호의 접두사인 경우가 없으므로, 답은 true입니다.

입출력 예 #3
첫 번째 전화번호, “12”가 두 번째 전화번호 “123”의 접두사입니다. 따라서 답은 false입니다.

 

풀이

처음 문제를 접하고 이 문제가 왜 해시 문제인지 파악하는데 조금 시간이 걸렸습니다. 이중루프로도 풀수 있을것 같아서였습니다. 하지만 그렇게 되면 아마 타임오버가 나오지 않을까 싶어서 좀 곰곰히 생각을 했습니다.

역시나 HashMap의 containsKey 함수를 아느냐 모르냐를 묻는 문제였습니다. 업무를 하다보면 containsKey 함수는 자주 사용되는 함수는 아니지만 이런 알고리즘 문제를 풀때는 종종 등장을 하는것 같습니다.

 

일단 phone_book의 배열을 모두 HashMap인 map에 넣고, phone_book 배열의 원소 String을 처음부터 j번까지 돌아가면서 map에 저장된 key 값이 있는지 확인하고 있다면 바로 false 해주도록 구현해 보았습니다.

import java.util.*;

class Solution {
    public boolean solution(String[] phone_book) {
        boolean answer = true;
        
        HashMap<String,Integer> map = new HashMap<String,Integer>();
        int i=0;
        for(String pb : phone_book){
            map.put(pb, i++);
        }
        
        for(i=0; i<phone_book.length; i++){
            for(int j=0; j<phone_book[i].length(); j++){
                if(map.containsKey(phone_book[i].substring(0,j))){
                    return false;
                }
            }
        }
        
        return answer;
    }
}

결과

728x90
반응형
728x90
반응형

완주하지 못한 선수(1Level)

문제설명

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

입출력 예

입출력 예 설명

예제 #1
"leo"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.

예제 #2
"vinko"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.

예제 #3
"mislav"는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.

 

풀이

이 문제는 해시를 얼마나 알고있는지에 대한 문제입니다. 해시를 쓰면 간단하게 Key를 통해 Value를 알 수 있습니다.

이 문제에는 함정이 있는데, 그건 바로 "참가자 중에는 동명이인이 있을 수 있습니다." 라는 것입니다. key값은 중복을 허용하지 않기때문에 이부분에 대한 내용을 어떻게 풀까가 중요한 것 같습니다.

import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        for(int i=0; i<participant.length ; i++){    
            if(map.get(participant[i]) == null){
                map.put(participant[i], 1);
            }else{
                map.put(participant[i], map.get(participant[i])+1);
            }
        }

        for(int i=0; i<completion.length ; i++){   
            if(map.get(completion[i]) != null){
                map.put(completion[i], map.get(completion[i])-1);
            }
        }
        
        for(int i=0; i<participant.length ; i++){  
            if(map.get(participant[i]) != 0){
                answer = participant[i] ;
                break;
            }
        }
        
        
        return answer;
    }
}

결과

728x90
반응형
728x90
반응형

K-번째수

문제설명

배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.

예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면

  1. array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.
  2. 1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.
  3. 2에서 나온 배열의 3번째 숫자는 5입니다.

배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • array의 길이는 1 이상 100 이하입니다.
  • array의 각 원소는 1 이상 100 이하입니다.
  • commands의 길이는 1 이상 50 이하입니다.
  • commands의 각 원소는 길이가 3입니다.

입출력 예

입출력 예 설명

[1, 5, 2, 6, 3, 7, 4]를 2번째부터 5번째까지 자른 후 정렬합니다. [2, 3, 5, 6]의 세 번째 숫자는 5입니다.
[1, 5, 2, 6, 3, 7, 4]를 4번째부터 4번째까지 자른 후 정렬합니다. [6]의 첫 번째 숫자는 6입니다.
[1, 5, 2, 6, 3, 7, 4]를 1번째부터 7번째까지 자릅니다. [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3입니다.

 

풀이

이번 문제는 정렬에 관련된 간단한 Level 1 문제입니다. Array 의 복사, 정렬등에 대한 함수를 알고 있는지 파악하려는 것 같습니다. 기본적인 문제이니 확실히 확인하는 것이 좋을것 같습니다.

import java.util.*;

class Solution {
    public int[] solution(int[] array, int[][] commands) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        
        for(int n=0; n<commands.length; n++){
            int i = commands[n][0];
            int j = commands[n][1];
            int k = commands[n][2];
            
            int[] tmp = Arrays.copyOfRange(array, i-1, j);
            Arrays.sort(tmp);
            ret.add(tmp[k-1]);
        }
        
        int[] answer = new int[ret.size()];
        for(int i=0; i<ret.size(); i++){
            answer[i] = ret.get(i);
        }

        return answer;
    }
}

결과

728x90
반응형
728x90
반응형

단어변환

문제설명

두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.

  1. 한 번에 한 개의 알파벳만 바꿀 수 있습니다.
  2. words에 있는 단어로만 변환할 수 있습니다.

예를 들어 begin이 "hit", target가 "cog", words가 ["hot","dot","dog","lot","log","cog"]라면 "hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환할 수 있습니다.

두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • 각 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
  • words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
  • begin과 target은 같지 않습니다.
  • 변환할 수 없는 경우에는 0를 return 합니다.

입출력 예

  • 각 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
  • words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
  • begin과 target은 같지 않습니다.
  • 변환할 수 없는 경우에는 0를 return 합니다.

입출력 예 설명

예제 #1
문제에 나온 예와 같습니다.

예제 #2
target인 "cog"는 words 안에 없기 때문에 변환할 수 없습니다.

 

풀이

해당문제는 전형적인 BFS문제입니다. BFS 문제의 경우 "최단","최소"를 찾는 경우가 많습니다. 문제에서도 단어가 변환되는 최소의 단계를 구하는 것이기 때문에 BFS 알고리즘을 사용하여 풀면 되겠습니다.

BFS 알고리즘의 설명은 아래를 참고하여 주십시오.

https://tylee82.tistory.com/329?category=940295 
 

[JAVA] 너비 우선 탐색 BFS(Breadth-first search)

동작방식 하나로 시작 정점을 방문한 후 시작 정점에 인접한 모든 정점들을 우선 방문하는 방법입니다. 더 이상 방문하지 않은 정점이 없을 때까지 방문하지 않은 모든 정점들에 대해서도 너비

tylee82.tistory.com

 

이외에도 isCanChange 함수에서 문자1(str1)과 문자2(str2)를 비교해 한개의 알파벳만 변환을 했는지 검사를 하는 함수가 있습니다. 저는 str1과 str2의 문자 하나하나를 char로 변환하여 빼기를 하여 절대값을 해주었습니다. 이렇게하면 문자의 차이가 나오는데 같은 문자라면 '0'이 나타날 것 입니다. '0'이 아닌 위치는 알파벳이 변환이 되었으니 이후에 나오는 알파벳은 모두 '0'이 나와야 한다는 가정으로 새우고 함수를 만들었습니다.

import java.util.*;

class Solution {
    
    class Word{
        String str;
        int count;
        
        Word(String str, int count){
            this.str = str;
            this.count = count;
        }
    }
    
    
    public boolean isCanChange(String str1, String str2){
    	//한 번에 한 개의 알파벳만 바꿀 수 있습니다.
        boolean ret = false;
        
        int len = str1.length();
        
        boolean isOneChange = false;
        int diffWord = 0;
        for(int i=0; i<len; i++){
            diffWord = Math.abs(str1.charAt(i) - str2.charAt(i));
            
            if(!isOneChange && diffWord != 0) {
            	isOneChange = true;
            	ret = true;
            }else if(isOneChange && diffWord != 0){
            	ret = false;
            	break;
            }
        }
        
        return ret;
    }

    
    public int solution(String begin, String target, String[] words) {
        int answer = 0;
        
        int[] used = new int[words.length]; // 사용한것은 1, 안한것은 0
        Queue<Word> q = new LinkedList<Word>();
        q.add(new Word(begin, 0)); //시작점
        
        while(!q.isEmpty()){
            
            Word cur = q.poll();
            
            if(cur.str.equals(target)){
                // terget과 문자가 동일하면 cur.count 반환하고 멈춤
                answer = cur.count;
                break;
            }
            
            for(int i=0; i<words.length; i++){
                if(isCanChange(cur.str, words[i] ) && used[i] == 0) //변환이 가능하고 사용하지 않았으면 q에 넣어준다.
                {
                    used[i] = 1; // 방문 표시
                    q.add(new Word(words[i] , cur.count+1));
                }
            }
            
        }
        
        
        return answer;
    }
}

결과

 

728x90
반응형
728x90
반응형

네트워크 문제

문제설명

네트워크란 컴퓨터 상호 간에 정보를 교환할 수 있도록 연결된 형태를 의미합니다. 예를 들어, 컴퓨터 A와 컴퓨터 B가 직접적으로 연결되어있고, 컴퓨터 B와 컴퓨터 C가 직접적으로 연결되어 있을 때 컴퓨터 A와 컴퓨터 C도 간접적으로 연결되어 정보를 교환할 수 있습니다. 따라서 컴퓨터 A, B, C는 모두 같은 네트워크 상에 있다고 할 수 있습니다.

컴퓨터의 개수 n, 연결에 대한 정보가 담긴 2차원 배열 computers가 매개변수로 주어질 때, 네트워크의 개수를 return 하도록 solution 함수를 작성하시오.

 

제한사항

  • 컴퓨터의 개수 n은 1 이상 200 이하인 자연수입니다.
  • 각 컴퓨터는 0부터 n-1인 정수로 표현합니다.
  • i번 컴퓨터와 j번 컴퓨터가 연결되어 있으면 computers[i][j]를 1로 표현합니다.
  • computer[i][i]는 항상 1입니다.

입출력 예

입출력 예 설명

예제 #1

아래와 같이 2개의 네트워크가 있습니다.

예제 #2

아래와 같이 1개의 네트워크가 있습니다.

 

풀이방법

프로그래머스에서 제공하는 코딩테스트 연습문제 Level 3 의 문제입니다. 일단 네트워크 문제는 분류가 깊이/너비 우선 탐색(DFS/BFS)로 분류가 되어있습니다. 하지만 저는 이 문제를 Union-Find로 풀어보려 합니다. 왜냐하면 연결된 그룹을 찾는 문제이고 주어진 입력값으로 각 컴퓨터를 연결하여 집합으로 묶어주면 그 집합의 개수만 카운트 해주면 될 것 같아서 저는 Union-Find 로 풀어보았습니다.

https://tylee82.tistory.com/291
 

[Java] Union-Find (유니온-파인드) 알고리즘

Union-Find는 자료 구조입니다. 그래프 알고리즘에서 사용하는 대표 알고리즘입니다. 여러개의 노드가 존재할 때 두 개의 노드를 선택해서, 현재 이 두 노드가 서로 같은 그래프에 속하는지 판별하

tylee82.tistory.com

import java.util.*;

class Solution {
    
    static int[] uArr;
    
    public int solution(int n, int[][] computers) {
        int answer = 0;
        uArr = new int[n+4];
        
        for(int i=0; i<n ; i++){
            for(int j=0; j<n ; j++){
                if(i==j) continue; // computer[i][i]는 항상 1 이기때문에 필요없음
                if(computers[i][j]==1){ // 연결된 컴퓨터끼리 Union 해줌
                    setUnion(i, j); 
                }
            }
        }
        
        // System.out.println("0:"+getFind(0));
        // System.out.println("1:"+getFind(1));
        // System.out.println("2:"+getFind(2));
        
        // 집합의 개수를 카운트하기위한 변수
        ArrayList<Integer> alist = new ArrayList<Integer>();
        for(int i=0; i<n ; i++){
            if( alist.contains(getFind(i)) ){
                // getFind로 찾은 집합의 우두머리가 이미 alist 변수에 있으면 pass
                continue;  
            } 
            else {
                // alist 에 없으면 추가
                alist.add(getFind(i));
            }
        }
        
        // 집합은 alist 의 size 이다.
        answer = alist.size();
        
        return answer;
    }
    
    public void setUnion(int i, int j){
        int a = getFind(i);
        int b = getFind(j);
        if(a == b) return;
        uArr[a] = b;
    }
    
    public int getFind(int tar){
        if(uArr[tar] == 0) return tar;
        int ret = getFind(uArr[tar]);
        uArr[tar] = ret;
        return ret;
    }
}

 

결과

728x90
반응형
728x90
반응형

신장트리(Spanning Tree)는 그래프 내의 모든 정점을 포함하는 트리입니다. MST(Minimum Spanning Tree)는 신장트리 중에서 사용된 간선들의 가중치 합이 최소인 트리를 이야기합니다. MST는 크루스칼 그리고 프림 알고리즘이 있습니다. 여기서는 크루스칼 알고리즘을 다루겠습니다.

 

  • 그래프 내의 간선의 숫자가 적은 희소 그래프의 경우 : 크루스칼 알고리즘
  • 그래프 내의 간선의 숫자가 많은 밀집 그래프의 경우 : 프림 알고리즘

동작방식

탐욕적 방법(Greedy)을 이용하여 가중치 그래프의 모든 정점을 최소 비용으로 연결하는 방법입니다.

  1. 그래프의 간선들을 가중치의 오름차순으로 정렬합니다.
  2. 정렬된 간선 리스트에서 순서대로 사이클을 형성하지 않는 간선을 선택합니다.
    • 즉, 가장 낮은 가중치를 먼저 선택합니다.
    • 사이클을 형성하는 간선을 제외합니다.
    • 해당 간선을 현재의 MST의 집합에 추가합니다.

시간복잡도

Union-Find 알고리즘을 이용하면 크루스칼 알고리즘의 시간 복접도는 간선들을 정렬하는 시간에 좌우됩니다.

간선 N개를 효율적으로 정렬한다면 O(N logN)의 시간복잡도를 갖는다.

참고사이트

https://hibee.tistory.com/300
 

[AL] 7. 최소 비용 신장 트리(MST) 알고리즘

7. 최소 비용 신장 트리(MST) 알고리즘 신장 트리 (Spanning Tree) 최소 비용 신장 트리 (MST) Kruskal MST 알고리즘 Prim MST 알고리즘 1. 신장 트리 (Spanning Tree) 1.1. Spanning Tree 그래프..

hibee.tistory.com

기본코드

입력값

7
11
1 2 2
2 7 7
7 6 9
6 5 23
5 4 1
4 1 10
1 3 3
2 3 3
3 7 4
3 6 3
3 5 6

코드

package study.graph;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

class A implements Comparable<A>{
	
	int a;
	int b;
	int dist;
	
	A (int a, int b, int dist){
		this.a = a;
		this.b = b;
		this.dist = dist;
	}


	@Override
	public int compareTo(A tar) {
		if(tar.dist < this.dist) return 1;
		if(tar.dist > this.dist) return -1;
		return 0;
	}
	
}

public class MST_크루스칼 {

	static int[] uArr = null;
	
	public static int getFind(int tar) {
		
		if(uArr[tar] == 0) return tar;
		int ret = getFind(uArr[tar]);
		uArr[tar] = ret;
		return ret;
	}
	
	public static void setUnion(int t1, int t2) {
		int a = getFind(t1);
		int b = getFind(t2);
		if(a == b) return;
		uArr[b] = a;
	}
	
	public static void main(String arg[]) throws IOException{
		
		System.setIn(new FileInputStream("input\\kruskal.txt"));
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		int N = Integer.parseInt(br.readLine()); // 정점의 개수
		int M = Integer.parseInt(br.readLine()); // 간선의 개수

		PriorityQueue<A> pq = new PriorityQueue<A>();
		
		StringTokenizer st = null; 
		for(int j=0; j<M; j++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			int dist = Integer.parseInt(st.nextToken());
			
			pq.add(new A(a, b, dist)); // 큐에 모든 간선을 넣는다.
			pq.add(new A(b, a, dist));
		}
		
		uArr = new int[N+1];
		
		int sumDist = 0;
		while(!pq.isEmpty()) {
			A tar = pq.poll();
			
			int start = tar.a;
			int end = tar.b;
			int a = getFind(start); // start 의 부모(root) 확인
			int b = getFind(end); // end 의 부모(root) 확인
			
			if(a == b) continue; // 부모가 같다면 사이클이 형성되어 있다고 판단하여 다음으로 진행
			
			setUnion(start, end); // 두개의 부모가 같지 않기 때문에 간선으로 연결가능, 그렇다면 유니온하여 부모로 설정
			sumDist += tar.dist; // 간선의 거리를 더한다.
		}
		
		bw.write("# " + sumDist + "\n");
		
		br.close();
		bw.close();
		
	}
	
}
728x90
반응형
728x90
반응형

 

신장트리(Spanning Tree)는 그래프 내의 모든 정점을 포함하는 트리입니다. MST(Minimum Spanning Tree)는 신장트리 중에서 사용된 간선들의 가중치 합이 최소인 트리를 이야기합니다. MST는 크루스칼 그리고 프림 알고리즘이 있습니다. 여기서는 프림알고리즘을 다루겠습니다.

 

  • 그래프 내의 간선의 숫자가 적은 희소 그래프의 경우 : 크루스칼 알고리즘
  • 그래프 내의 간선의 숫자가 많은 밀집 그래프의 경우 : 프림 알고리즘

 

동작방식

시작 정점에서부터 출발하여 신장트리 집합을 단계적으로 확장해 나가는 방법

  1. 시작 단계에서는 시작 정점만이 MST 에 포함합니다.
  2. 앞 단계에서 만들어진 MST 집합에 인접한 정점들 중에서 최소 간선으로 연결된 정점을 선택하여 트리를 확장합니다.
    • 즉, 가장 낮은 가중치를 먼저 선택합니다.
  3. 위의 과정을 트리가 N-1 개의 간선을 가질 때까지 반복합니다.

시간복잡도

기본적으로 O(N^2) 의 시간복잡도를 가지고 있습니다. 우선순위 큐를 사용한다면 O( E logV)의 시간복잡도를 가집니다.

참고사이트

https://hibee.tistory.com/300
 

[AL] 7. 최소 비용 신장 트리(MST) 알고리즘

7. 최소 비용 신장 트리(MST) 알고리즘 신장 트리 (Spanning Tree) 최소 비용 신장 트리 (MST) Kruskal MST 알고리즘 Prim MST 알고리즘 1. 신장 트리 (Spanning Tree) 1.1. Spanning Tree 그래프..

hibee.tistory.com

기본코드

7
11
1 2 2
2 3 5
1 3 20
1 4 10
4 5 1
5 6 23
3 6 3
3 5 6
7 6 9
7 3 2
2 7 7
package study.graph;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;

class B implements Comparable<B>{
	int n;
	int dist;
	
	B (int a, int b){
		this.n = a;
		this.dist = b;
	}

	@Override
	public int compareTo(B tar) {
		if(tar.dist < this.dist) return 1;
		if(tar.dist > this.dist) return -1;
		return 0;
	}
	
	
}

public class MST_프림 {

	public static void main(String[] args) throws IOException {
		
		System.setIn(new FileInputStream("input\\prim.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		int N = Integer.parseInt(br.readLine());
		int M = Integer.parseInt(br.readLine());
		
		int[] used = new int[N+1]; // 방문 여부 (0: 미방문, 1: 방문)
		
		ArrayList<ArrayList<B>> alist = new ArrayList<ArrayList<B>>();
		for(int i=0; i<=N; i++) {
			alist.add(new ArrayList<B>());
		}
		
		StringTokenizer st = null;
		for(int m=1; m<=M; m++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			int dist = Integer.parseInt(st.nextToken());
			
			alist.get(a).add(new B(b, dist));
			alist.get(b).add(new B(a, dist));
		}
		
		PriorityQueue<B> pq = new PriorityQueue<B>();
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(1); // 임의의 한 노드를 지정
		int sumDist = 0;
		
		while(!q.isEmpty()) {
			int currentNode = q.poll();
			used[currentNode] = 1; // 방문표시
			
			// 현재 노드에 연결된 간선을 pq에 넣음(방문한 노드는 제외)
			for(int i=0; i<alist.get(currentNode).size(); i++) {
				if(used[alist.get(currentNode).get(i).n] != 1) {
					pq.add(alist.get(currentNode).get(i));
				}
			}
			
			while(!pq.isEmpty()) {
				B tar = pq.poll();
				
				if(used[tar.n] == 1) continue; // 방문한 노드면 pass
				
				used[tar.n]= 1;// 방문표시
				sumDist += tar.dist;
				q.add(tar.n); // 연결된 노드를 큐에 넣어줌
				break; // pq에서 방문하지 않은 노드로 가는 가장 dist가 작은 것을 석택해주었으니 여기서 멈춤
			}
		}
		
		bw.write("# " + sumDist);
		
		bw.close();
		br.close();
		
	}
}
728x90
반응형
728x90
반응형

올해 초부터 모니터를 사고싶은 마음이 굴뚝같았지만, 마음에 드는 모니터가 없어서 기다리고 있었습니다. 가끔씩 다나와에서 모니터를 조회해보고 있었는데, 얼마전 마음에 90%정도 드는 모니터를 발견하여 2~3일 고민끝에 과감하게 구입을 했습니다. 

바로 GIGABYTE M32U 라는 제품이였습니다. 상세 스팩은 아래와 같습니다.

제가 원했던 모니터의 조건은 아래와 같습니다.

  1. 향후 5년이상 사용할 모니터
  2. PS5에 호환되는 HDMI 2.1 을 지원하는 모니터
  3. 4K 해상도에 HDR을 지원
  4. 32인치 크기
  5. USB Type-C 지원 

M32U 모니터의 경우 제가 원하는 스펙을 가장 부합하였고 고민끝에 구매를 하게되었습니다. 구매는 할인 쿠폰을 먹여서 대략 80만원 초반에 구입을 하였습니다.

배송도 빨라 주문한지 하루문에 배송이 되었습니다. 대기업의 제품과 달리 모니터 박스는 컬러풀하지는 않습니다. 비슷한 성능의 제품이 100만원 이상인 것이라 생각되면 이러한 부분에 절약을 했다고 생각이 드는 부분입니다.

공식유통사를 통한 제품에는 아래와 같이 정품인증 스티커가 있는데 이 스티커를 모니터 우측하단에 부착하라고 합니다. 향후 A/S를 위하여 잊지 말고 부착을 해줘야합니다. 

솔직히 기가바이트 A/S를 삼성이나 LG와 같은 등급으로 생각하면 안됩니다. 모든 A/S는 택배를 통해서 이루어진다고 생각을 하면됩니다. 용산과 가까운 곳에 거주를 하면 방문 A/S를 생각해도 되겠지만 대부분 택배를 이용하게 될것 같습니다. 그래서 박스는 버리지 마십시오. 32인치 모니터가 들어갈만한 박스를 구하기도 힘들고 배송과정에 제품이 고장날 수 있기때문에 박스는 필히 보관하여야 합니다.

내부를 개봉해보았습니다. 스텐드와 케이블들이 보이는데 전원 케이블 및 DP 1.4(1m), HDMI 2.1(1m), SS USB (1m) 케이블로 구성되어 있습니다.

우선 스탠드를 조립합니다. 스탠드 무게가 대략 2~3kg정도 하는 것 같습니다. 저는 모니터 암을 사용할 예정이긴 합니다만, 스탠드로도 한번 설치를 해보려 합니다. 스탠드는 별도의 드라이버 없이도 설치가 가능합니다.

모니터 입력 단자는 아래와 같이 구성이 되어있습니다. HDMI 2개, DP 1개, Type-C 1개, SS USB 1개, USB 3.0 3개, 헤드폰아웃 1개 입니다.

모니터를 컴퓨터에 연결하고 테스트 해보았습니다. 일단 IPS 패널이라 빚샘이 있긴한데 심각하지 않습니다. 다른 성능 테스트도 괜찮습니다. 모니터 해상도 주사율도 연결하니 바로 나타납니다.

모니터 성능 테스트는 아래 사이트에서 가능합니다.

https://www.monitor.co.kr/a/1/
 

monitor.co.kr - 모니터 불량화소 테스트 사이트

"안녕하세요. 본 웹서비스는 실시간으로 모니터의 불량화소 증상을 점검하는 온라인 프로그램으로써 총 8가지 색이 준비되어 있습니다." 1. 사용방법은 아주 간단하고 쉽습니다. 2. 키보드 F11 키

www.monitor.co.kr

 

스탠드 설치와 모니터암 설치 모습입니다. 사용을 하며 몇가지 단점이 있었습니다.

 

  1. 리모콘이 없어서 전환이 불편함
  2. 스피커 성능은 모니터 스피커 치고는 괜찮지만 별도 스피커 사용이 좋음

단점이긴 하지만 조금 불편한 정도 입니다. 사용을 하면서 다른 부분이 생기면 수정하도록 하겠습니다.

 

 

 

※ 직접 구입하여 실제 사용해보고 작성하는 리뷰 글 입니다. ※

728x90
반응형
728x90
반응형

얼마전 PC 스피커 오른쪽이 나왔다 안나왔다를 반복하더니 결국 왼쪽만 소리가 나오는 상황이 되었습니다. 2만원정도 가격의 저렴한 스피커였는데 드디어 수명이 다했나 봅니다. 모니터도 스피커가 존재하는데 모니터에 내장된 스피커 성능은 아무리 좋아도 저렴한 스피커에 비교되지 않을 정도로 찢어지고 울리는 소리가 심합니다. 그래서 이번에 PC 스피커를 구매하려 알아보았습니다. 일단 구매 조건은 아래와 같습니다.

  1. 10~15만원정도의 가격
  2. 책상위에 물건이 많아 최대한 작은 사이즈와 무게
  3. 2.0 채널 (베이스까지 필요없음)
  4. PC뿐만 아니라 블루투스 가능하면 좋음
  5. 리모컨이 있으면 좋음

1,2,3번은 필수였고, 4,5번은 옵션이지만 되도록 모든 조건은 만족하는 제품을 찾아보았습니다. 일단 다나와에서 가격과 PC 스피커 검색시 인기순위(2021년 10월)는 아래와 같았습니다.

 

순위로 살펴보면 1위인 Creative T100, 2위 T40 II, 3위 캔스폰 R30BT PLUS, 4위 SPS300BT 정도가 고려대상이 되겠습니다. 일단 무게와 크기로 3위 R30BT PLUS 는 탈락입니다. 2위 T40 II도 크기가 커보이고 디자인도 마음에 들지 않았습니다. 4위 SPS300BT의 경우 1위인 Creative T100보다 크기가 커서 1위인 Creative T100로 결정하였습니다. 

 

좋은 스피커는 아니지만 그래도 10만원이 넘는 스피커를 처음으로 구매하는데 조금 낭비가 아닌가 하는 생각도 들었지만, 이제는 찢어지는 소리와 작별을 하고 싶어서 마음을 먹고 구입을 하였습니다.

내부 구성은 간단했습니다. 포장도 잘되어있어 충격에도 제품을 보호할 정도의 꼼꼼함이 보였습니다.

스피커의 구성은 아래와 같습니다.

아직 정리를 하지않은 상태에서 이번에 새로 구입한 32인치 모니터와 함께 두니 멋있음이 느껴집니다. 역시 전자제품은 검정이 진리인듯 합니다. 아직 모니터암을 설치하지 않은 상태이긴 한데 모니터 스텐드 최대 높이인데도 스피커 높이가 조금 높긴 합니다. 

 

아래는 테스트로 유튜브 음악을 틀어보았을때 동영상으로 촬영을 해보았습니다. 전문장비가 없이 폰으로 찍은거니 감안해서 들어보시고 참고하십시오.

 

일단 해당 제품에 대한 소리 테스트시 확실히 기존에 저가형 스피커보다는 좋은 음질인 것은 확실히 느껴집니다. 소리의 깊이가 다르다고 말할 수 있겠습니다. 하지만 몇일 사용하면 느낀것은 스피커에 디스플레이가 없어 현재 PC와 연결되어있지 블루투스와 연결되었는지 그리고 BASS 음량이나 기타 부가 정보를 확인할 방법이 없습니다. 이부분에 대한 것은 좀 아쉽지만 크기와 무게 그리고 디자인, 음질까지 전반적으로 만족 스럽습니다.

 

728x90
반응형
728x90
반응형

얼마전 플립Z3를 구매하며 트레이드인으로 기존에 사용하던 폰을 반납하여 추가 보상을 받으려 신청하였습니다. 개통후 14일 이내에 중고폰을 민팃 중고폰 atm에 반납하면 삼성전자에서 추가보상으로 조금더 보상을 해주는 제도입니다. 트레이드인 제도에 대한 설명은 아래 링크에서 확인 가능합니다.

https://www.samsung.com/sec/trade-in/home/
 

갤럭시 트레이드인 | 삼성닷컴

중고폰 추가보상 프로그램

www.samsung.com

 

개통후 집앞에 SKT 매장에 민팃 중고폰 atm이 있어서 그곳에서 반납을 하려하니, 삼성전자 추가보상 대상자라는 메시지가 나타나지 않았습니다. 일단 판매는 하지 않고 다시 돌아와 살펴보니 SKT 매장에서는 반납이 불가하다고 합니다.

 

그래서 근처 이마트로 가서 다시 반납을 하려하니 이번에도 추가보상 대상자 메시지가 나타지 않습니다. 이상함을 느끼고 하나하나 살펴보던중 주문자정보의 휴대폰번호를 잘 못 입력해두었습니다. 그래서 대상자로 나타나지 않았던것 같습니다. 민팃 고객센터에 연락을 해보았더니(고객센터 전화 엄청 오래기다려야 합니다.) 주문자 정보에대한 변경권한이 없다고 합니다. 저는 구매처가 삼성닷컴이라 삼성닷컴으로 문의를 해야한다고 안내를 받았습니다. 

 

근데 삼성닷컴 구매문의(1588-6084) 전화를 해보면 알겠지만, 기다려지지도 않고 통화가 폭주하여 다음에 다시 걸어달라고 끊어버립니다. 이틀동안 전화를 하다가 삼성전자 서비스(1588-3366)로 전화를 하여 상담원을 연결하였습니다. 상황을 듣고 전자서비스에서 관여하는 업무가 아니라 삼성닷컴쪽에 부서 연결을 확인하여 주더니, 연결이 안되어 저녁에 저에게 전화를 줄수 있도록 예약을 해준다고 하였습니다. 전화 연결이 불가능한 상황이니 일단 예약을 하고 기다렸습니다. 전화는 점심쯤 왔습니다. 주문자 정보 수정은 지금 불가능 하고, 일단 주문자 정보가 다른 부분을 확인, 휴대폰 번호를 주문자가 사용한다는 서류를 제출하고, 민팃에 중고폰을 일반 판매하여 차후에 삼성전자 추가보상을 지급하겠다고 안내를 해주었습니다.

 

전화 온 날이 개통후 13일정도 되는 날이라 바로 이마트로 달려가 일반판매를 하였습니다. 민팃에 중고폰 판매하는 방법은 생각보다 간단했습니다. 화면에 아무런 이상도 없었는데 중잔상이라는 판정을 하더군요. 그래도 중고거래나 따로 파는 것보다는 안전할 것 같다는 생각이 들어서 64,000원에 판매를 했습니다. 

이후 현재 사용하는 통신사(당시에는 U+망 알뜰폰 사용중)에 연락을하여 가입사실확인서를 발급받고, 해당 서류를 안내원이 알려준 번호로 전송하였습니다.

이렇게 하고나면 2~3주후에 추가보상금에 관련된 SMS를 받을 수 있다고합니다. 글을 작성중인 지금 일주정도 지나서 아직 SMS가 오지 않았습니다.

중고폰 판매 2주가 되는 시점에 추가보상이 들어왔습니다. 원래 정상적으로 판매를 했다면 아래 블로그 글과 같이 되어야 합니다.

https://blog.naver.com/onnuribike/222499620158
 

민팃 ATM 중고폰 판매 후기 갤럭시 Z플립 구매 추가보상 15만원

이번에 갤럭시 Z플립3을 구매하였는데요~ 기존에 사용하던 중고폰을 반납하면 추가보상을 해준다고 해서 ...

blog.naver.com

 

주문자 정보를 잘 못 입력한 저의 잘못이기 때문에 좀 고생을 했습니다. 혹시 추가보상이 안나온다면 주문시 작성한 주문정보를 꼭 확인하여 보십시오.

728x90
반응형

+ Recent posts