친구끼리 쪽지를 주고받을 때 쓰는 암호가 있다.
낱말의 길이가 L일 때, L을 2로 나눈 몫을 h라 하자.
낱말의 앞쪽 h글자를 거꾸로 쓰고, 뒤쪽 h글자도 따로 거꾸로 쓴다.
L이 홀수이면 한가운데에 글자 하나가 남는데, 이 글자는 제자리에 그대로 둔다.
예를 들어 notebook은 note와 book을 저마다 뒤집어 etonkoob이 된다.
pencils는 pen과 ils를 저마다 뒤집고 가운데 c는 그대로 두어 nepcsli가 된다.
그래서 길이가 3 이하인 낱말은 암호로 바꾸어도 그대로다.
첫 줄에 낱말 수 n이, 다음 n줄에 낱말이 하나씩 주어진다.
낱말마다 암호로 바꾼 문자열을 한 줄에 출력하라.
입력
1 ≤ n ≤ 100. 낱말은 길이 1 ~ 1,000이고 영어 대문자·소문자와 숫자로만 이루어진다
출력
n줄, 줄마다 암호로 바꾼 낱말
예시 1 · stdin
4
notebook
pencils
ab
x
stdout
etonkoob
nepcsli
ab
x
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
문자열의 한 조각을 뒤집는 법이 언어마다 달라요. Python은 s[:h][::-1](조각을 거꾸로 읽은 새 문자열), JS·TS는 문자열에 reverse가 없어서 [...t].reverse().join(""), Java는 new StringBuilder(t).reverse().toString(), C#은 char[]로 바꿔 Array.Reverse(a, 시작, 개수), C는 양 끝에서 가운데로 오며 두 글자를 맞바꾸는 반복문, C++는 std::reverse(s.begin(), s.begin() + h), 크레이콘은 s.부분문자열(0, h).뒤집기(). Python·JS·Java·크레이콘 풀이는 뒤집은 새 문자열을 만들어 잇고, C·C++·C#(char 배열) 풀이는 그 자리에서 고쳐요. 조각을 가리키는 두 수의 뜻도 달라요. Python s[a:b], JS slice(a, b), Java substring(a, b), C++ std::reverse(처음, 끝)은 (시작, 끝)이고 끝 자리는 들어가지 않아요. C# Array.Reverse(배열, 시작, 개수)와 크레이콘 부분문자열(시작, 개수)는 (시작, 개수)예요. 함정 여섯: ① 뒤쪽 절반을 h번 자리부터 잡으면 길이가 홀수일 때 한가운데 글자까지 뒤집혀요(예시의 pencils가 nepslic로). 뒤쪽은 (길이 − h)번 자리부터예요. ② Python s[-h:]와 JS s.slice(-h)는 '끝에서 h글자'이지만, h가 0이면 -0이 0이라서 문자열 전체가 돼요(예시의 x가 xx로). ③ Python reversed(t)는 문자열이 아니라 반복자를 줘요. str(reversed(t))는 <reversed object at …>라는 글자가 되니 "".join(reversed(t))로 이어야 해요. ④ JS 배열의 reverse()는 새 배열을 주지 않고 그 배열 자체를 뒤집어요. 한 배열을 뒤집은 다음 또 잘라 쓰면 이미 뒤집힌 것을 자르게 돼요. ⑤ C에서 맞바꾸는 반복문을 구간의 가운데에서 멈추지 않고 끝까지 돌리면, 두 번 바뀌어 처음 그대로예요(notebook이 그대로 나와요). ⑥ (시작, 개수)를 받는 곳에 끝 자리를 넣는 실수: C# Array.Reverse(a, 길이 − h, 길이)는 배열을 벗어나 ArgumentException으로 멈추고, 크레이콘 s.부분문자열(h, 길이 − h)는 오류 없이 가운데 글자에 뒤쪽 절반까지 붙여서 잘라 와요(notebook이 etonbookkoob로).
Pythonmain.py · 8 줄
n = int(input())for _ in range(n): s = input().strip() h = len(s) // 2 # 앞쪽 h글자, 한가운데(길이가 홀수일 때만 한 글자), 뒤쪽 h글자 front, middle, back = s[:h], s[h:len(s) - h], s[len(s) - h:] # [::-1]은 거꾸로 읽은 새 문자열을 만든다 print(front[::-1] + middle + back[::-1])
JavaScriptmain.js · 15 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);// 문자열에는 reverse가 없어서 글자 배열로 바꿔 뒤집고 다시 잇는다const reversed = (t) => [...t].reverse().join("");const out = [];for (let i = 1; i <= n; i++) { const s = lines[i].trim(); const h = Math.floor(s.length / 2); // 앞쪽 h글자, 한가운데(길이가 홀수일 때만 한 글자), 뒤쪽 h글자 const front = s.slice(0, h); const middle = s.slice(h, s.length - h); const back = s.slice(s.length - h); out.push(reversed(front) + middle + reversed(back));}console.log(out.join("\n"));
TypeScriptmain.ts · 16 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);// 문자열에는 reverse가 없어서 글자 배열로 바꿔 뒤집고 다시 잇는다const reversed = (t: string): string => [...t].reverse().join("");const out: string[] = [];for (let i = 1; i <= n; i++) { const s: string = lines[i].trim(); const h: number = Math.floor(s.length / 2); // 앞쪽 h글자, 한가운데(길이가 홀수일 때만 한 글자), 뒤쪽 h글자 const front: string = s.slice(0, h); const middle: string = s.slice(h, s.length - h); const back: string = s.slice(s.length - h); out.push(reversed(front) + middle + reversed(back));}console.log(out.join("\n"));
JavaMain.java · 27 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Main { // String은 고칠 수 없어서 StringBuilder에 담아 뒤집는다 static String reversed(String t) { return new StringBuilder(t).reverse().toString(); } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) { String s = in.readLine().trim(); int len = s.length(); int h = len / 2; // substring(시작, 끝): 끝 자리는 들어가지 않는다 String front = s.substring(0, h); String middle = s.substring(h, len - h); String back = s.substring(len - h); out.append(reversed(front)).append(middle).append(reversed(back)).append('\n'); } System.out.print(out); }}
C#Main.cs · 22 줄
using System;using System.Text;class Program{ static void Main() { int n = int.Parse(Console.ReadLine().Trim()); var sb = new StringBuilder(); for (int i = 0; i < n; i++) { // string은 고칠 수 없어서 char 배열로 바꿔 그 자리에서 뒤집는다 char[] a = Console.ReadLine().Trim().ToCharArray(); int h = a.Length / 2; // Array.Reverse(배열, 시작, 개수): 셋째 값은 끝 자리가 아니라 개수다 Array.Reverse(a, 0, h); Array.Reverse(a, a.Length - h, h); sb.Append(new string(a)).Append('\n'); } Console.Write(sb); }}
C++main.cpp · 17 줄
#include <algorithm>#include <iostream>#include <string>int main() { int n; std::cin >> n; for (int i = 0; i < n; i++) { std::string s; std::cin >> s; auto h = s.size() / 2; // std::reverse(시작, 끝): 끝은 들어가지 않는다. 그 자리에서 뒤집는다 std::reverse(s.begin(), s.begin() + h); std::reverse(s.end() - h, s.end()); std::cout << s << '\n'; }}
Cmain.c · 28 줄
#include <stdio.h>#include <string.h>/* s[from] ~ s[to]를 그 자리에서 뒤집는다. 양 끝에서 가운데로 오며 맞바꾼다 */static void reverse_range(char *s, int from, int to) { while (from < to) { char tmp = s[from]; s[from] = s[to]; s[to] = tmp; from++; to--; }}int main(void) { int n; static char s[1001]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%1000s", s); int len = (int)strlen(s); int h = len / 2; reverse_range(s, 0, h - 1); /* 앞쪽 h글자 */ reverse_range(s, len - h, len - 1); /* 뒤쪽 h글자 */ printf("%s\n", s); } return 0;}
Craykonmain.cray · 11 줄
n = 콘솔.줄읽기().수로변환();반복 (i = 0; i < n; i++){ s = 콘솔.줄읽기().공백제거(); h = 수학.몫(s.길이, 2); // 부분문자열(시작, 개수): 둘째 값은 끝 자리가 아니라 글자 수다 앞쪽 = s.부분문자열(0, h); 가운데 = s.부분문자열(h, s.길이 - 2 * h); 뒤쪽 = s.부분문자열(s.길이 - h, h); 콘솔.쓰기(앞쪽.뒤집기() + 가운데 + 뒤쪽.뒤집기());}