가게 유리문 안쪽에 안내문을 붙이면, 밖에서는 좌우가 뒤집힌 모양으로 보인다.
그래서 안쪽에서 붙일 거울 글씨를 미리 만들어, 밖에서 바르게 읽히게 하려고 한다.
첫 줄에 줄 수 n이 주어지고, 다음 n줄에 안내문이 한 줄씩 주어진다. 안내문은 왼쪽 맞춤으로 쓰여 있다.
안내문의 줄마다 거울 글씨를 만들어 입력과 같은 차례로 출력한다. 줄의 차례는 바꾸지 않는다.
거울 글씨는 먼저 그 줄의 글자 차례를 맨 끝부터 맨 앞까지 거꾸로 뒤집은 것이다.
그다음, 거울에 비치면 서로 모양이 바뀌는 글자를 짝끼리 맞바꾼다.
짝은 ( 와 ), [ 와 ], { 와 }, < 와 >, / 와 \, 소문자 b 와 d, 소문자 p 와 q 의 일곱 쌍이다.
예를 들어 ( 는 ) 가 되고 ) 는 ( 가 된다. 짝이 없는 글자(빈칸, 숫자, 대문자, 다른 글자)는 그대로 둔다.
왼쪽 맞춤인 글을 좌우로 뒤집으면 오른쪽 맞춤이 된다. 그래서 가장 긴 줄의 길이를 L이라 하면, 줄마다 앞에 빈칸을 (L − 그 줄의 길이)개 붙여 출력한다. 가장 긴 줄에는 빈칸을 붙이지 않는다.
입력
1 ≤ n ≤ 50. 줄마다 길이 1 ~ 200이고 ASCII 글자(코드 32~126)만 쓰며, 맨 앞과 맨 끝은 빈칸이 아니다
출력
n줄
예시 1 · stdin
3
(open) 9-18
<- push door
bread & pie
stdout
81-9 (neqo)
roob hsuq ->
eiq & baerd
예시 2 · stdin
2
a/b\c
[sale] {today}
stdout
c/d\a
{yabot} [elas]
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
뒤집기는 Python s[::-1], Java new StringBuilder(s).reverse(), C# 글자 배열을 Array.Reverse 한 뒤 new string(c), C++ std::reverse(s.begin(), s.end()), 크레이콘 s.뒤집기()예요. JS·TS 문자열에는 reverse가 없어서 [...s].reverse().join("")처럼 배열을 거쳐요. 함정은 맞바꾸기예요. s.replace("(", ")").replace(")", "(")처럼 차례로 바꾸면 처음에 바꾼 ) 까지 다시 ( 가 되어 둘 다 ( 로 남아요. 입력은 코드 32~126 글자만 쓰니, 입력에 나올 수 없는 글자(여기서는 코드 1)에 한쪽을 잠깐 맡겨 두고 세 번 바꾸면 돼요: a → 맡김, b → a, 맡김 → b. 글자를 하나씩 보며 짝이 있으면 짝으로 바꿔 새 문자열에 붙이는 한 번 훑기도 똑같이 맞아요. 모두 바꾸기는 Python replace, JS replaceAll(TS는 split(a).join(b)도 흔해요), Java replace(char, char), C# Replace(char, char), C++ <algorithm>의 std::replace, 크레이콘 s.바꾸기(a, b)예요. C에는 바꾸기 함수가 없어서, 양 끝에서 맞바꾸며 뒤집을 때 짝 글자로 바꿔 넣는 게 자연스러워요. 역슬래시는 문자열 안에서 "\\"처럼 두 번 써야 한 글자예요(모든 언어 공통, 크레이콘도 같아요). 오른쪽 맞춤은 모든 줄을 다 만든 뒤에야 가장 긴 길이를 알 수 있어서, 줄을 모아 두었다가 출력해요. 앞을 채우는 것은 Python s.rjust(L), JS·TS s.padStart(L), C# s.PadLeft(L), C printf("%*s", L, s), 크레이콘 s.앞채우기(L)이고, Java·C++는 빈칸 (L − 길이)개를 앞에 붙여요(Java " ".repeat(k), C++ std::string(k, ' ')). 뒤를 채우면(padEnd) 줄 끝 빈칸이라 왼쪽 맞춤 그대로예요. 거울은 좌우만 뒤집으니 줄의 차례까지 뒤집으면 안 돼요.
Pythonmain.py · 19 줄
TMP = "\x01" # 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다PAIRS = [("(", ")"), ("[", "]"), ("{", "}"), ("<", ">"), ("/", "\\"), ("b", "d"), ("p", "q")]def swap(s, a, b): """s 안의 a와 b를 서로 맞바꾼다. a → b, b → a를 차례로 하면 둘 다 a가 되어 버린다.""" return s.replace(a, TMP).replace(b, a).replace(TMP, b)n = int(input())out = []for _ in range(n): s = input()[::-1] # 좌우를 뒤집는다(줄의 차례는 그대로) for a, b in PAIRS: s = swap(s, a, b) out.append(s)width = max(len(s) for s in out) # 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다print("\n".join(s.rjust(width) for s in out))
JavaScriptmain.js · 17 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const TMP = "\x01"; // 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다const PAIRS = [["(", ")"], ["[", "]"], ["{", "}"], ["<", ">"], ["/", "\\"], ["b", "d"], ["p", "q"]];// s 안의 a와 b를 서로 맞바꾼다. a → b, b → a를 차례로 하면 둘 다 a가 되어 버린다const swap = (s, a, b) => s.replaceAll(a, TMP).replaceAll(b, a).replaceAll(TMP, b);const out = [];for (let k = 1; k <= n; k++) { let s = [...lines[k]].reverse().join(""); // 문자열에는 reverse가 없어 배열로 뒤집는다 for (const [a, b] of PAIRS) s = swap(s, a, b); out.push(s);}// 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다const width = Math.max(...out.map((s) => s.length));console.log(out.map((s) => s.padStart(width)).join("\n"));
TypeScriptmain.ts · 19 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const TMP = "\x01"; // 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다const PAIRS: [string, string][] = [["(", ")"], ["[", "]"], ["{", "}"], ["<", ">"], ["/", "\\"], ["b", "d"], ["p", "q"]];// s 안의 a와 b를 서로 맞바꾼다. a → b, b → a를 차례로 하면 둘 다 a가 되어 버린다const swap = (s: string, a: string, b: string): string => s.split(a).join(TMP).split(b).join(a).split(TMP).join(b);const out: string[] = [];for (let k = 1; k <= n; k++) { let s: string = [...lines[k]].reverse().join(""); // 문자열에는 reverse가 없어 배열로 뒤집는다 for (const [a, b] of PAIRS) s = swap(s, a, b); out.push(s);}// 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다const width: number = Math.max(...out.map((s) => s.length));console.log(out.map((s) => s.padStart(width)).join("\n"));
JavaMain.java · 31 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Main { static final char TMP = '\u0001'; // 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다 static final String PAIRS = "()[]{}<>/\\bdpq"; // 두 글자씩 짝 public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine().trim()); String[] mirrored = new String[n]; int width = 0; for (int k = 0; k < n; k++) { String s = new StringBuilder(br.readLine()).reverse().toString(); // 좌우를 뒤집는다 for (int i = 0; i < PAIRS.length(); i += 2) { char a = PAIRS.charAt(i), b = PAIRS.charAt(i + 1); // a → b, b → a를 차례로 하면 둘 다 a가 되므로 잠깐 TMP에 맡긴다 s = s.replace(a, TMP).replace(b, a).replace(TMP, b); } mirrored[k] = s; width = Math.max(width, s.length()); } // 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다 StringBuilder out = new StringBuilder(); for (String s : mirrored) { out.append(" ".repeat(width - s.length())).append(s).append('\n'); } System.out.print(out); }}
C#Main.cs · 33 줄
using System;using System.Text;class Program{ const char Tmp = '\u0001'; // 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다 const string Pairs = "()[]{}<>/\\bdpq"; // 두 글자씩 짝 static void Main() { int n = int.Parse(Console.ReadLine().Trim()); var mirrored = new string[n]; int width = 0; for (int k = 0; k < n; k++) { char[] c = Console.ReadLine().ToCharArray(); Array.Reverse(c); // 좌우를 뒤집는다 string s = new string(c); for (int i = 0; i < Pairs.Length; i += 2) { char a = Pairs[i], b = Pairs[i + 1]; // a → b, b → a를 차례로 하면 둘 다 a가 되므로 잠깐 Tmp에 맡긴다 s = s.Replace(a, Tmp).Replace(b, a).Replace(Tmp, b); } mirrored[k] = s; width = Math.Max(width, s.Length); } // 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다 var sb = new StringBuilder(); foreach (string s in mirrored) sb.Append(s.PadLeft(width)).Append('\n'); Console.Write(sb); }}
C++main.cpp · 32 줄
#include <algorithm>#include <iostream>#include <string>#include <vector>int main() { const char tmp = '\x01'; // 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다 const std::string pairs = "()[]{}<>/\\bdpq"; // 두 글자씩 짝 int n; std::cin >> n; std::string s; std::getline(std::cin, s); // n 뒤의 줄바꿈을 버린다 std::vector<std::string> mirrored; std::size_t width = 0; for (int k = 0; k < n; k++) { std::getline(std::cin, s); std::reverse(s.begin(), s.end()); // 좌우를 뒤집는다 for (std::size_t i = 0; i < pairs.size(); i += 2) { char a = pairs[i], b = pairs[i + 1]; // a → b, b → a를 차례로 하면 둘 다 a가 되므로 잠깐 tmp에 맡긴다 std::replace(s.begin(), s.end(), a, tmp); std::replace(s.begin(), s.end(), b, a); std::replace(s.begin(), s.end(), tmp, b); } width = std::max(width, s.size()); mirrored.push_back(s); } // 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다 for (const std::string& line : mirrored) { std::cout << std::string(width - line.size(), ' ') << line << '\n'; }}
Cmain.c · 35 줄
#include <stdio.h>#include <string.h>/* 짝이 있는 글자는 짝으로, 없는 글자는 그대로 돌려준다 */static char mirror(char ch) { static const char pairs[] = "()[]{}<>/\\bdpq"; /* 두 글자씩 짝 */ const char *p = strchr(pairs, ch); if (p == NULL || ch == '\0') return ch; int i = (int)(p - pairs); return i % 2 == 0 ? pairs[i + 1] : pairs[i - 1];}int main(void) { int n, width = 0; static char lines[50][256]; char buf[256]; fgets(buf, sizeof buf, stdin); sscanf(buf, "%d", &n); for (int k = 0; k < n; k++) { char *line = lines[k]; fgets(line, sizeof lines[k], stdin); line[strcspn(line, "\r\n")] = '\0'; int len = (int)strlen(line); /* C에는 문자열 바꾸기가 없어서, 양 끝에서 맞바꾸며 뒤집을 때 짝 글자로도 바꾼다 */ for (int i = 0, j = len - 1; i <= j; i++, j--) { char a = line[i], b = line[j]; line[i] = mirror(b); line[j] = mirror(a); } if (len > width) width = len; } /* 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다: %*s는 너비를 받아 앞을 빈칸으로 채운다 */ for (int k = 0; k < n; k++) printf("%*s\n", width, lines[k]); return 0;}
Craykonmain.cray · 24 줄
맡김 = 글자.글자로변환(1); // 입력에 나오지 않는 글자(입력은 코드 32~126만 쓴다)를 잠깐 맡아 두는 자리로 쓴다짝 = ["(", ")", "[", "]", "{", "}", "<", ">", "/", "\\", "b", "d", "p", "q"]; // 두 개씩 짝n = 콘솔.줄읽기().수로변환();거울 = [];너비 = 0;반복 (k = 0; k < n; k += 1){ s = 콘솔.줄읽기().뒤집기(); // 좌우를 뒤집는다(줄의 차례는 그대로) 반복 (i = 0; i < 짝.개수; i += 2) { // a → b, b → a를 차례로 하면 둘 다 a가 되므로 잠깐 맡김 글자에 맡긴다 s = s.바꾸기(짝[i], 맡김).바꾸기(짝[i + 1], 짝[i]).바꾸기(맡김, 짝[i + 1]); } 거울.넣기(s); 만약 (s.길이 > 너비) { 너비 = s.길이; }}// 왼쪽 맞춤이 뒤집히면 오른쪽 맞춤이 된다각각 (줄 에서 거울){ 콘솔.쓰기(줄.앞채우기(너비));}