알고리즘/백준

백준 5052번 - 전화번호 목록 / Go

Hwisaek 2022. 5. 1. 01:28
반응형

문제: https://www.acmicpc.net/problem/5052

 

5052번: 전화번호 목록

첫째 줄에 테스트 케이스의 개수 t가 주어진다. (1 ≤ t ≤ 50) 각 테스트 케이스의 첫째 줄에는 전화번호의 수 n이 주어진다. (1 ≤ n ≤ 10000) 다음 n개의 줄에는 목록에 포함되어 있는 전화번호가

www.acmicpc.net

문제 설명

더보기

문제

전화번호 목록이 주어진다. 이때, 이 목록이 일관성이 있는지 없는지를 구하는 프로그램을 작성하시오.

전화번호 목록이 일관성을 유지하려면, 한 번호가 다른 번호의 접두어인 경우가 없어야 한다.

예를 들어, 전화번호 목록이 아래와 같은 경우를 생각해보자

  • 긴급전화: 911
  • 상근: 97 625 999
  • 선영: 91 12 54 26

이 경우에 선영이에게 전화를 걸 수 있는 방법이 없다. 전화기를 들고 선영이 번호의 처음 세 자리를 누르는 순간 바로 긴급전화가 걸리기 때문이다. 따라서, 이 목록은 일관성이 없는 목록이다. 

입력

첫째 줄에 테스트 케이스의 개수 t가 주어진다. (1 ≤ t ≤ 50) 각 테스트 케이스의 첫째 줄에는 전화번호의 수 n이 주어진다. (1 ≤ n ≤ 10000) 다음 n개의 줄에는 목록에 포함되어 있는 전화번호가 하나씩 주어진다. 전화번호의 길이는 길어야 10자리이며, 목록에 있는 두 전화번호가 같은 경우는 없다.

출력

각 테스트 케이스에 대해서, 일관성 있는 목록인 경우에는 YES, 아닌 경우에는 NO를 출력한다.

예제 입력 1 복사

2
3
911
97625999
91125426
5
113
12340
123440
12345
98346

예제 출력 1 복사

NO
YES
​

출처

ICPC > Regionals > Europe > Northwestern European Regional Contest > Nordic Collegiate Programming Contest > NCPC 2007 A번


 


정답

package main

import (
	"bufio"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	rd := bufio.NewReader(os.Stdin)
	wr := bufio.NewWriter(os.Stdout)

	t, _ := strconv.Atoi(scan5052(rd))
	for i := 0; i < t; i++ {
		n, _ := strconv.Atoi(scan5052(rd))
		numberList := make([]string, 0, n)
		for i := 0; i < n; i++ {
			numberList = append(numberList, scan5052(rd))
		}
		_, _ = wr.WriteString(solution5052(numberList)+"\n")
	}

	_ = wr.Flush()
}

func solution5052(numberList []string) (result string) {
	sort.Slice(numberList, func(i, j int) bool {
		return numberList[i] < numberList[j]
	})
	lenNumberList := len(numberList)
	for i := 0; i < lenNumberList-1; i++ {
		if len(numberList[i]) >= len(numberList[i+1]) {
			continue
		}
		if numberList[i] == numberList[i+1][:len(numberList[i])] {
			return "NO"
		}
	}
	return "YES"
}

func scan5052(rd *bufio.Reader) string {
	str, _ := rd.ReadString('\n') // 여기서 text는 마지막에 줄바꿈 문자를 포함하므로
	str = strings.TrimSpace(str)  // 줄바꿈 문자를 제거해야 함
	return str
}

 


풀이

 코드는 다 짜 놓고 줄 바꿈을 하지 않아서 10번 정도 시도한 문제이다....

 

문제의 해결방법은 전화번호를 문자열로 입력받아서 정렬한 다음, 하나씩 비교하면서 지금 전화번호가 바로 다음 전화번호의 접두어인지 확인하면 된다.

 

 Trei를 이용해서도 문제를 풀 수 있다고도 하지만, 문자열을 정렬하게 되면 사전 순으로 정렬을 하므로 접두어가 무조건 앞에 오게 되어 이 방식으로 풀 수 있다.

 

 Golang에서는 sort.Strings()이라는 문자열 배열 정렬 메서드도 제공하는데, 이 문제를 통해 해당 메서드보다 sort.Slice()를 이용하는 게 시간이 더 빠르다는 것과 strings.hasPrefix()보다 "numberList[i] == numberList[i+1][:len(numberList[i])]"이 더 빠르다는 것을 확인할 수 있었다. 다음에 유사한 문제가 나왔을 때, 시간적으로 더 유리한 방법으로 사용해야겠다.

반응형