[Python] 1071 소트

2022. 6. 20. 01:07· Algorithm/Greedy
목차
  1. A. 접근
  2. B. 문제 풀이
  3. 전체 코드
  4. B-1. 준비
  5. B-2. 풀이

문제

N개의 정수가 주어지면, 이것을 연속된 두 수가 연속된 값이 아니게 정렬(A[i] + 1 ≠ A[i+1])하는 프로그램을 작성하시오. 가능한 것이 여러 가지라면 사전순으로 가장 앞서는 것을 출력한다.

입력

첫째 줄에 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 N개의 수가 주어진다. N개의 수는 1,000보다 작거나 같은 자연수 또는 0이다.

출력

첫째 줄에 문제의 정답을 출력한다.

문제 풀이

A. 접근

권국원님의 「보통의 취준생을 위한 코딩 테스트 with 파이썬」을 참고하여 작성함

이틀 동안 고민했는데 못 풀었다. 다양한 접근을 생각해야 하는데 뭔가 하나에 꽂히면 그곳에 집중하여 다른 풀이를 생각하지 못한다 ㅠㅠ
문제의 핵심은 연속된 값이 아니게 정렬하는 프로그램을 작성하는 것이다. 또한, 사전순으로 가장 앞서는 것을 출력하도록 한다.

예를 들어,

3
1 2 3

이러한 입력이 주어졌을 때는

1 3 2

이렇게 연속되지 않으며 사전순으로 가장 앞서게 출력할 수 있다.

또한,

9
1 1 1 1 2 2 2 2 2

이러한 입력이 주어졌을 때,

2 2 2 2 2 1 1 1 1

이렇게 출력해야 한다.

조금 더 예제 입력을 분석해보자.

6
1 2 3 4 5 6

은

1 3 2 4 6 5

이렇게 출력이 된다.
그리고

6
1 1 2 2 3 3

은

1 1 3 3 2 2

이런 식으로 출력이 된다.

출력을 보면서 규칙을 파악해 보자면, a[i]과 a[i] + 1, a[i] + 2가 존재할 때는 항상 a[i] 뒤에 a[i] + 2가 붙어있다.
하지만, a[i]와 a[i] + 1이 존재할 때는 a[i] + 1이 모두 출력이 되어야 a[i]가 출력이 된다.

즉, 조건을 조금 더 명확히 표현하면 다음과 같다.

  1. a[i] + 1을 만족하는 수가 있다.
    1. a[i] + 2 이상을 만족하는 수가 있다면, a[i]를 모두 출력한 다음 a[i] + 2를 한 번 출력한다.
    2. 그렇지 않다면, a[i] + 1을 출력한다.
  2. 그렇지 않다면 a[i]를 모두 출력한다.

1-1에서 a[i] + 2를 한 번 출력한 이유는 사전순으로 가장 앞서는 수를 찾기 위해서다. 이는 1-2도 동일하다. 사실 2번도 동일한 이유이다. 골드 1 문제라고 해도 사실 분석만 잘 하면 풀 수 있는데 너무 티어를 보고 쫄지 말자!

B. 문제 풀이

전체 코드

n = int(input())

cnt_sort = [0 for i in range(1002)]

arr = [int(i) for i in input().split()]
for i in range(n):
    cnt_sort[arr[i]] += 1

ans = ''

while True:
    switch = False
    for i in range(1001):
        if cnt_sort[i]:
            switch = True
            if cnt_sort[i + 1]:
                k = -1
                for j in range(i + 2, 1001):
                    if cnt_sort[j]:
                        k = j
                        break
                if k != -1:
                    while cnt_sort[i]:
                        ans += str(i) + ' '
                        cnt_sort[i] -= 1
                    ans += str(k) + ' '
                    cnt_sort[k] -= 1
                    break
                else:
                    ans += str(i + 1) + ' '
                    cnt_sort[i + 1] -= 1
                    break
            else:
                while cnt_sort[i]:
                    ans += str(i) + ' '
                    cnt_sort[i] -= 1
                break
    if switch == False:
        break

print(ans)

B-1. 준비

n = int(input())

cnt_sort = [0 for i in range(1002)]

arr = [int(i) for i in input().split()]
for i in range(n):
    cnt_sort[arr[i]] += 1

ans = ''

이번에는 계수 정렬을 사용한다. 같은 수가 계속해서 나오고 수의 개수도 1000개 이하라서 쓰기에 무리가 없다. 그래서 cnt_sort라는 변수를 만들었고, for문으로 각 수의 등장 횟수를 저장한다.

B-2. 풀이

while True:
    switch = False
    for i in range(1001):
        if cnt_sort[i]:
            switch = True
            if cnt_sort[i + 1]:
                k = -1
                for j in range(i + 2, 1001):
                    if cnt_sort[j]:
                        k = j
                        break
                if k != -1:
                    while cnt_sort[i]:
                        ans += str(i) + ' '
                        cnt_sort[i] -= 1
                    ans += str(k) + ' '
                    cnt_sort[k] -= 1
                    break
                else:
                    ans += str(i + 1) + ' '
                    cnt_sort[i + 1] -= 1
                    break
            else:
                while cnt_sort[i]:
                    ans += str(i) + ' '
                    cnt_sort[i] -= 1
                break
    if switch == False:
        break

print(ans)

먼저 while 문의 반복 조건을 설정하기 위해 switch 변수를 만들었다. for문으로 1부터 1000까지 순회한다. 다 순회했는데 값이 없다면 정렬이 종료된 것이므로 while 반복을 종료한다.

--------if cnt_sort[i + 1]:
                k = -1
                for j in range(i + 2, 1001):
                    if cnt_sort[j]:
                        k = j
                        break
                if k != -1:
                    while cnt_sort[i]:
                        ans += str(i) + ' '
                        cnt_sort[i] -= 1
                    ans += str(k) + ' '
                    cnt_sort[k] -= 1
                    break
                else:
                    ans += str(i + 1) + ' '
                    cnt_sort[i + 1] -= 1
                    break

만약 i + 1 값이 있다고 할 때의 조건을 구현하였다.

k는 i + 2 값이 있는지 확인하기 위해 설정한 변수이다.
i + 2부터 1000까지 순회하면서 값이 있는지 파악한다. 만약 값이 있다면 그 값이 a[i] 다음에 와야 한다. 그래서 k에 값을 저장한다.

그렇게 하여 k에 값이 있다면(i + 2 이상의 값이 존재한다면) i 값을 모두 ans에 출력 형식에 맞춰 저장하고 카운팅을 1씩 뺀다. 그 이후에 a[k] 값도 ans에 붙이고 카운팅을 1 뺀다.

k에 값이 없다면 i + 1이 먼저 출력되어야 하므로 ans에 i + 1 값을 붙이고 카운팅을 1 뺀다.

------------else:
                while cnt_sort[i]:
                    ans += str(i) + ' '
                    cnt_sort[i] -= 1
                break
    if switch == False:
        break

print(ans)

i + 1이 없다면 i값을 모두 출력하도록 한다. 왜냐하면 사전순으로 가장 앞서는 값을 출력하기 위해서다.

총평

그리디를 조금 더 풀어볼 필요가 있다. 화이팅

 

저작자표시 비영리 (새창열림)

'Algorithm > Greedy' 카테고리의 다른 글

[Python] 13305 주유소  (0) 2022.06.20
[Python] 1489 대결  (0) 2022.06.20
[Python] 1083 소트  (0) 2022.06.19
[Python] 1931 회의실 배정  (0) 2022.06.15
[Python] 1541 잃어버린 괄호  (0) 2022.06.15
  1. A. 접근
  2. B. 문제 풀이
  3. 전체 코드
  4. B-1. 준비
  5. B-2. 풀이
'Algorithm/Greedy' 카테고리의 다른 글
  • [Python] 13305 주유소
  • [Python] 1489 대결
  • [Python] 1083 소트
  • [Python] 1931 회의실 배정
턴태
턴태
import { Dream } from "future";
턴태
턴태의 밑바닥부터 시작하는 de-vlog
턴태
전체
오늘
어제
  • ROOT (187)
    • Node.js (37)
      • ES6 (1)
      • TypeScript (3)
      • Express.js (16)
      • NestJS (16)
      • JS (24)
    • 프론트엔드 (29)
      • CS (5)
    • 백엔드 (1)
      • 검색 (2)
      • Database (1)
    • 기타 툴 (1)
      • git (1)
    • 데브옵스 & 인프라 (19)
      • Kubernetes (15)
      • Docker (2)
      • Monitoring (1)
      • IaC (1)
    • Algorithm (90)
      • Implementation & simulation (5)
      • Math (4)
      • Brute Force (1)
      • String (0)
      • Graph (5)
      • Recursion & Backtracking (19)
      • Divide & Conquer (2)
      • Dynamic Programming (18)
      • Greedy (13)
      • Priority Queue (2)
      • Binary Search (6)
      • Data Structure (7)
      • Shortest Path (5)
      • Minimum Spanning Tree (1)
      • Sorting (1)
      • Prefix Sum (1)
    • Linux (1)
      • Ubuntu (1)
    • Diary (5)
      • Algorithm (1)
      • Conference (1)
      • Retrospective (3)
    • Book (0)
      • Self-Development (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • backtracking
  • Express
  • 토이프로젝트
  • 인프런X디프만
  • 오먹
  • 익스프레스
  • 타입스크립트
  • baekjoon
  • 다이나믹 프로그래밍
  • GREEDY
  • 디프만
  • 함수형 프로그래밍
  • TypeScript
  • 파이썬
  • Kubernetes
  • 백준
  • N과 M
  • 백트래킹
  • node.js
  • Omuk
  • python
  • 자바스크립트
  • k8s
  • dynamic programming
  • 노드
  • 쿠버네티스
  • nestjs
  • Toy Project
  • 네스트
  • 인프런

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
턴태
[Python] 1071 소트
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.