첫 줄에 n, 둘째 줄에 정수 n개로 된 목록이 주어진다. 셋째 줄에 명령 수 q가 주어지고, 다음 q줄에 "l r"이 하나씩 주어진다(1 ≤ l ≤ r ≤ n, 자리는 1부터 센다). 명령마다 목록의 l번째부터 r번째까지를 제자리에서 거꾸로 뒤집어라. 명령은 주어진 차례대로, 앞 명령이 바꾼 목록에 이어서 적용한다. 모든 명령을 마친 목록을 빈칸 하나씩 띄워 한 줄로 출력하라. 목록과 구간을 받아 뒤집는 함수(두 칸의 자리를 바꾸는 함수를 써서)를 만들어 풀어 보자.
입력
1 ≤ n ≤ 1,000, 1 ≤ q ≤ 1,000, 모든 수는 -1,000,000,000 이상 1,000,000,000 이하의 정수
출력
한 줄: 마지막 목록
예시 1 · stdin
5
1 2 3 4 5
2
1 3
3 5
stdout
3 2 5 4 1
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
양 끝 칸을 바꾸고 안쪽으로 한 칸씩 좁히되 l < r일 때만 바꿔요. 끝까지(i <= r) 돌면 가운데를 지나 다시 바꿔서 원래대로 돌아가요. 두 칸 바꾸기: Python a[i], a[j] = a[j], a[i], JavaScript·TypeScript [a[i], a[j]] = [a[j], a[i]], C++ std::swap(a[i], a[j]), C# (a[i], a[j]) = (a[j], a[i]), Java·C·크레이콘은 임시 변수 t. 함수에 넘길 때가 핵심이에요. 수 하나를 그냥 넘기면 어느 언어든 값이 복사되어 넘어가서, Python def swap(x, y): x, y = y, x나 C void swap(int x, int y)는 함수 안의 복사본만 바꾸고 목록은 그대로예요. 목록은 Python·JavaScript·TypeScript·Java·C#·크레이콘 모두 같은 목록이 넘어가서(가리키는 값이 복사됨) 함수 안에서 칸을 바꾸면 밖에서도 바뀌어요. 그래서 목록과 번호를 넘기면 돼요. C는 주소를 넘겨 void swap(int *x, int *y), C#은 ref int x로 변수 자체를 넘길 수 있어요. C++은 조심: void f(std::vector<int> a)는 vector를 통째로 복사해 받아서 바꿔도 밖이 그대로라 std::vector<int>& a(참조)로 받아야 해요.
Pythonmain.py · 15 줄
def reverse_range(a, l, r): """a[l..r](0부터)를 제자리에서 뒤집는다. 목록은 함수 밖의 것과 같은 것이다.""" while l < r: a[l], a[r] = a[r], a[l] l += 1 r -= 1n = int(input())a = list(map(int, input().split()))q = int(input())for _ in range(q): l, r = map(int, input().split()) reverse_range(a, l - 1, r - 1)print(*a)
JavaScriptmain.js · 16 줄
const nums = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);// 배열은 같은 것이 넘어오므로 함수 안에서 바꾸면 밖에서도 바뀐다function reverseRange(a, l, r) { while (l < r) { [a[l], a[r]] = [a[r], a[l]]; l++; r--; }}const n = nums[0];const a = nums.slice(1, 1 + n);const q = nums[1 + n];for (let k = 0; k < q; k++) reverseRange(a, nums[2 + n + 2 * k] - 1, nums[3 + n + 2 * k] - 1);console.log(a.join(" "));
TypeScriptmain.ts · 17 줄
import { readFileSync } from "node:fs";const nums: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);// 배열은 같은 것이 넘어오므로 함수 안에서 바꾸면 밖에서도 바뀐다function reverseRange(a: number[], l: number, r: number): void { while (l < r) { [a[l], a[r]] = [a[r], a[l]]; l++; r--; }}const n: number = nums[0];const a: number[] = nums.slice(1, 1 + n);const q: number = nums[1 + n];for (let k = 0; k < q; k++) reverseRange(a, nums[2 + n + 2 * k] - 1, nums[3 + n + 2 * k] - 1);console.log(a.join(" "));
JavaMain.java · 31 줄
import java.util.Scanner;import java.util.StringJoiner;public class Main { // 배열은 참조가 복사되어 넘어오므로 칸을 바꾸면 밖의 배열이 바뀐다 static void swap(int[] a, int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; } static void reverseRange(int[] a, int l, int r) { while (l < r) swap(a, l++, r--); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) a[i] = sc.nextInt(); int q = sc.nextInt(); for (int k = 0; k < q; k++) { int l = sc.nextInt(); int r = sc.nextInt(); reverseRange(a, l - 1, r - 1); } StringJoiner out = new StringJoiner(" "); for (int v : a) out.add(String.valueOf(v)); System.out.println(out); }}
C#Main.cs · 29 줄
using System;using System.Linq;class Program{ // ref로 받으면 넘긴 변수 자체를 바꾼다(a[i], a[j] 칸을 직접) static void Swap(ref int x, ref int y) { (x, y) = (y, x); } static void ReverseRange(int[] a, int l, int r) { while (l < r) Swap(ref a[l++], ref a[r--]); } static void Main() { Console.ReadLine(); int[] a = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); int q = int.Parse(Console.ReadLine()); for (int k = 0; k < q; k++) { int[] lr = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); ReverseRange(a, lr[0] - 1, lr[1] - 1); } Console.WriteLine(string.Join(" ", a)); }}
C++main.cpp · 22 줄
#include <iostream>#include <utility>#include <vector>// vector를 &(참조)로 받아야 밖의 것이 바뀐다. 그냥 받으면 복사본만 바뀐다void reverse_range(std::vector<int>& a, int l, int r) { while (l < r) std::swap(a[l++], a[r--]);}int main() { int n, q, l, r; std::cin >> n; std::vector<int> a(n); for (int& v : a) std::cin >> v; std::cin >> q; for (int k = 0; k < q; k++) { std::cin >> l >> r; reverse_range(a, l - 1, r - 1); } for (int i = 0; i < n; i++) std::cout << (i ? " " : "") << a[i]; std::cout << "\n";}
Cmain.c · 26 줄
#include <stdio.h>/* 값이 아니라 주소를 받아야 넘긴 칸이 바뀐다 */void swap(int *x, int *y) { int t = *x; *x = *y; *y = t;}void reverse_range(int *a, int l, int r) { while (l < r) swap(&a[l++], &a[r--]);}int main(void) { int n, q, l, r, a[1000]; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d", &q); for (int k = 0; k < q; k++) { scanf("%d %d", &l, &r); reverse_range(a, l - 1, r - 1); } for (int i = 0; i < n; i++) printf(i ? " %d" : "%d", a[i]); putchar('\n'); return 0;}
Craykonmain.cray · 27 줄
// 목록은 같은 것이 넘어오므로 함수 안에서 칸을 바꾸면 밖에서도 바뀐다자리바꾸기(목록, i, j){ t = 목록[i]; 목록[i] = 목록[j]; 목록[j] = t;}구간뒤집기(목록, l, r){ 동안 (l < r) { 자리바꾸기(목록, l, r); l += 1; r -= 1; }}n = 콘솔.줄읽기().수로변환();a = 콘솔.수들읽기();q = 콘솔.줄읽기().수로변환();반복 (k = 0; k < q; k++){ lr = 콘솔.수들읽기(); 구간뒤집기(a, lr[0] - 1, lr[1] - 1);}콘솔.쓰기(a);