{ }codelper
자리 바꾸기목록 번호P0317

가장 작은 학생은 맨 앞, 가장 큰 학생은 맨 뒤

체육 시간에 학생 n명이 한 줄로 서 있다. 선생님이 맞바꾸기를 딱 두 번 해서 줄을 다듬는다. 첫째로, 키가 가장 작은 학생과 맨 앞에 선 학생이 자리를 맞바꾼다. 키가 가장 작은 학생이 여럿이면 그 가운데 가장 앞에 선 학생이 바꾼다. 둘째로, 첫째 맞바꾸기를 마친 줄에서 키가 가장 큰 학생과 맨 뒤에 선 학생이 자리를 맞바꾼다. 키가 가장 큰 학생이 여럿이면 그 가운데 가장 뒤에 선 학생이 바꾼다. 바꿀 학생이 이미 그 자리에 서 있으면 아무 일도 일어나지 않는다. 첫 줄에 n이, 둘째 줄에 앞에서부터 차례로 학생들의 키가 빈칸 하나씩 띄워 주어진다. 두 번의 맞바꾸기를 마친 줄의 키를 앞에서부터 차례로 빈칸 하나씩 띄워 한 줄에 출력하라.

입력
1 ≤ n ≤ 1,000.
키는 100 이상 200 이하의 정수이다
출력
한 줄: 맞바꾸기를 두 번 마친 줄의 키 n개
예시 1 · stdin
4
180 160 150 170
stdout
150 160 170 180
예시 2 · stdin
6
160 150 175 150 175 160
stdout
150 160 175 150 160 175
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

자리를 찾고 두 칸을 맞바꾸는 도구가 언어마다 달라요.
처음 나오는 자리는 Python a.index(v), JS·TS a.indexOf(v), C# Array.IndexOf(a, v), C++ std::min_element(가리키는 것을 돌려줘요), 크레이콘 a.자리찾기(v).
마지막으로 나오는 자리는 JS·TS a.lastIndexOf(v), C# Array.LastIndexOf(a, v), C++는 std::max_element(a.rbegin(), a.rend())처럼 뒤에서부터 보게 해요.
Python 목록에는 뒤에서 찾는 메서드가 없어서 뒤집은 목록에서 찾아 자리를 다시 계산하고, Java 배열·C·크레이콘은 반복문으로 찾아요.
반복문에서는 <로 견주면 처음 자리가, >=로 견주면 마지막 자리가 남아요.
맞바꾸기는 Python a[0], a[i] = a[i], a[0], JS·TS [a[0], a[i]] = [a[i], a[0]], C# (a[0], a[i]) = (a[i], a[0]), C++ std::swap(a.front(), *it)이고, Java·C·크레이콘은 임시 변수를 써요.
함정 다섯: ① 두 자리를 미리 다 찾아 두고 맞바꾸기를 두 번 하면, 가장 큰 학생이 맨 앞에 있었을 때 첫째 맞바꾸기로 그 학생이 옮겨 가서 적어 둔 자리가 낡아요(예시 1이 170 160 180 150으로).
둘째 자리는 첫째 맞바꾸기 뒤에 찾아요.
② Python에서 a[0], a[a.index(min(a))] = a[a.index(min(a))], a[0]처럼 자리 계산을 왼쪽에 그대로 쓰면, 왼쪽은 앞에서부터 하나씩 넣기 때문에 a[0]에 가장 작은 값이 들어간 뒤에 a.index(min(a))가 다시 계산돼 0이 돼요.
넣은 값을 곧바로 덮어써서 맞바꾸기가 없던 일이 돼요(예시 1이 170 160 150 180으로).
자리를 먼저 변수에 담아요.
③ 같은 키가 여럿일 때: 가장 작은 키를 <=로 찾으면 마지막 자리가 잡히고, C++ std::max_element(a.begin(), a.end())와 Python a.index(max(a))는 처음 자리를 줘요.
값은 같아도 맞바꾼 상대가 달라져서 줄이 달라져요(예시 2).
④ C의 XOR 묘기 *x ^= *y; *y ^= *x; *x ^= *y;는 두 주소가 같은 칸이면 자기 자신과 XOR 해서 0이 돼요.
가장 작은 학생이 이미 맨 앞일 때가 바로 그 경우예요.
⑤ 임시 변수 없이 a[0] = a[i]; a[i] = a[0];라고 쓰면 첫 줄에서 a[0]의 원래 값이 사라져 두 칸이 같아져요.

Pythonmain.py · 12 줄
n = int(input())a = list(map(int, input().split())) # 가장 작은 키가 처음 나오는 자리를 먼저 변수에 담아 두고 맞바꾼다i = a.index(min(a))a[0], a[i] = a[i], a[0] # 가장 큰 키는 첫째 맞바꾸기를 마친 줄에서 다시 찾는다. 뒤집은 줄에서 처음 나오는 자리가 마지막 자리다j = n - 1 - a[::-1].index(max(a))a[n - 1], a[j] = a[j], a[n - 1] print(*a)
JavaScriptmain.js · 13 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const a = lines[1].trim().split(/\s+/).map(Number); // 가장 작은 키가 처음 나오는 자리const i = a.indexOf(Math.min(...a));[a[0], a[i]] = [a[i], a[0]]; // 가장 큰 키는 첫째 맞바꾸기를 마친 줄에서 다시 찾는다. lastIndexOf는 마지막으로 나오는 자리를 준다const j = a.lastIndexOf(Math.max(...a));[a[n - 1], a[j]] = [a[j], a[n - 1]]; console.log(a.join(" "));
TypeScriptmain.ts · 14 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const a: number[] = lines[1].trim().split(/\s+/).map(Number); // 가장 작은 키가 처음 나오는 자리const i: number = a.indexOf(Math.min(...a));[a[0], a[i]] = [a[i], a[0]]; // 가장 큰 키는 첫째 맞바꾸기를 마친 줄에서 다시 찾는다. lastIndexOf는 마지막으로 나오는 자리를 준다const j: number = a.lastIndexOf(Math.max(...a));[a[n - 1], a[j]] = [a[j], a[n - 1]]; console.log(a.join(" "));
JavaMain.java · 38 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer; public class Main {    // Java에는 한 줄 맞바꾸기가 없다. 배열과 두 자리를 받아 임시 변수로 바꾼다    static void swap(int[] a, int i, int j) {        int tmp = a[i];        a[i] = a[j];        a[j] = tmp;    }     public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        int[] a = new int[n];        StringTokenizer st = new StringTokenizer(in.readLine());        for (int k = 0; k < n; k++) a[k] = Integer.parseInt(st.nextToken());         // 가장 작은 키가 처음 나오는 자리: 더 작을 때만(<) 바꾼다        int i = 0;        for (int k = 1; k < n; k++) if (a[k] < a[i]) i = k;        swap(a, 0, i);         // 첫째 맞바꾸기를 마친 줄에서, 가장 큰 키가 마지막으로 나오는 자리: 같을 때도(>=) 바꾼다        int j = 0;        for (int k = 1; k < n; k++) if (a[k] >= a[j]) j = k;        swap(a, n - 1, j);         StringBuilder out = new StringBuilder();        for (int k = 0; k < n; k++) {            if (k > 0) out.append(' ');            out.append(a[k]);        }        System.out.println(out);    }}
C#Main.cs · 21 줄
using System;using System.Linq; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine().Trim());        int[] a = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();         // 가장 작은 키가 처음 나오는 자리        int i = Array.IndexOf(a, a.Min());        (a[0], a[i]) = (a[i], a[0]);         // 가장 큰 키는 첫째 맞바꾸기를 마친 줄에서 다시 찾는다. LastIndexOf는 마지막으로 나오는 자리를 준다        int j = Array.LastIndexOf(a, a.Max());        (a[n - 1], a[j]) = (a[j], a[n - 1]);         Console.WriteLine(string.Join(" ", a));    }}
C++main.cpp · 21 줄
#include <algorithm>#include <iostream>#include <vector> int main() {    int n;    std::cin >> n;    std::vector<int> a(n);    for (int& x : a) std::cin >> x;     // min_element는 가장 작은 값이 처음 나오는 자리를 가리킨다    auto smallest = std::min_element(a.begin(), a.end());    std::swap(a.front(), *smallest);     // max_element도 처음 나오는 자리를 준다. 뒤에서부터 보면(rbegin) 마지막으로 나오는 자리가 된다    auto tallest = std::max_element(a.rbegin(), a.rend());    std::swap(a.back(), *tallest);     for (int k = 0; k < n; k++) std::cout << (k ? " " : "") << a[k];    std::cout << '\n';}
Cmain.c · 29 줄
#include <stdio.h> /* 값이 아니라 칸의 주소를 받아야 배열이 바뀐다 */static void swap(int *x, int *y) {    int tmp = *x;    *x = *y;    *y = tmp;} int main(void) {    int n;    static int a[1000];    scanf("%d", &n);    for (int k = 0; k < n; k++) scanf("%d", &a[k]);     /* 가장 작은 키가 처음 나오는 자리: 더 작을 때만(<) 바꾼다 */    int i = 0;    for (int k = 1; k < n; k++) if (a[k] < a[i]) i = k;    swap(&a[0], &a[i]);     /* 첫째 맞바꾸기를 마친 줄에서, 가장 큰 키가 마지막으로 나오는 자리: 같을 때도(>=) 바꾼다 */    int j = 0;    for (int k = 1; k < n; k++) if (a[k] >= a[j]) j = k;    swap(&a[n - 1], &a[j]);     for (int k = 0; k < n; k++) printf(k ? " %d" : "%d", a[k]);    printf("\n");    return 0;}
Craykonmain.cray · 34 줄
// 두 자리를 맞바꾼다. 목록은 넘겨받은 그 목록이 바뀐다맞바꾸기(줄, i, j){    임시 = 줄[i];    줄[i] = 줄[j];    줄[j] = 임시;} n = 콘솔.줄읽기().수로변환();a = 콘솔.수들읽기(); // 가장 작은 키가 처음 나오는 자리: 더 작을 때만(<) 바꾼다i = 0;반복 (k = 1; k < n; k++){    만약 (a[k] < a[i])    {        i = k;    }}맞바꾸기(a, 0, i); // 첫째 맞바꾸기를 마친 줄에서, 가장 큰 키가 마지막으로 나오는 자리: 같을 때도(>=) 바꾼다j = 0;반복 (k = 1; k < n; k++){    만약 (a[k] >= a[j])    {        j = k;    }}맞바꾸기(a, n - 1, j); 콘솔.쓰기(a);