キーボードで英語を打つとき、文字ごとに打つ手が決まっている。 左手の文字は q w e r t a s d f g z x c v b の 15 個で、右手の文字は y u i o p h j k l n m の 11 個である。 大文字は同じ小文字と同じ手で打つ。 英字でない文字(数字、空白、句読点)はどちらの手の文字でもない。 一行の文字列が与えられる。 文字列の中で、英字が 1 個以上、間にほかの文字を挟まずにすぐ続いていて、それらがすべて同じ手の文字である部分を片手のかたまりという。 三行を出力せよ。 一行目には、いちばん長い片手のかたまりの長さを出力する。 二行目には、そのかたまりを入力に出たとおり(大文字小文字もそのまま)出力する。 いちばん長いかたまりが複数あれば、いちばん左のものを出力する。 英字が一つもなければ、一行目に 0 を、二行目に "-" を出力する。 三行目には、すぐ隣り合う二つの文字がどちらも英字で、しかも違う手の文字であるところの数を出力する。 二つの英字の間にほかの文字が一つでも挟まっていれば、その二つは隣り合っていない。
LEFT = set("qwertasdfgzxcvb")RIGHT = set("yuiophjklnm")def hand(ch): """영어 글자면 "L"·"R", 아니면 None. 대문자는 소문자로 바꿔 찾는다.""" c = ch.lower() if c in LEFT: return "L" if c in RIGHT: return "R" return Nones = input()best_len, best_start = 0, -1run = 0 # 지금 글자에서 끝나는 한 손 덩이의 길이switches = 0prev = None # 바로 앞 글자의 손(글자가 아니면 None)for i, ch in enumerate(s): h = hand(ch) if h is None: run = 0 elif h == prev: run += 1 else: if prev is not None: switches += 1 # 바로 붙은 두 글자의 손이 다르다 run = 1 # 새 덩이는 이 글자부터 # 글자마다 견주면 줄 끝에서 끝나는 덩이도 놓치지 않는다. >라서 같으면 왼쪽 것이 남는다 if run > best_len: best_len, best_start = run, i - run + 1 prev = hprint(best_len)print(s[best_start:best_start + best_len] if best_len else "-")print(switches)
JavaScriptmain.js · 21 行
const s = require("fs").readFileSync(0, "utf8").split("\n")[0].replace(/\r$/, "");const LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm";// 영어 글자면 "L"·"R", 아니면 null. 대문자는 소문자로 바꿔 찾는다// (includes는 부분 문자열을 찾으니 빈칸·기호 한 글자도 들어갈 수 없게 글자 하나만 넘긴다)const hand = (ch) => { const c = ch.toLowerCase(); return LEFT.includes(c) ? "L" : RIGHT.includes(c) ? "R" : null;};let bestLen = 0, bestStart = -1, run = 0, switches = 0, prev = null;for (let i = 0; i < s.length; i++) { const h = hand(s[i]); if (h === null) run = 0; else if (h === prev) run++; else { if (prev !== null) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h;}console.log(`${bestLen}\n${bestLen ? s.slice(bestStart, bestStart + bestLen) : "-"}\n${switches}`);
TypeScriptmain.ts · 23 行
import { readFileSync } from "node:fs";const s: string = readFileSync(0, "utf8").split("\n")[0].replace(/\r$/, "");const LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm";type Hand = "L" | "R" | null;// 영어 글자면 "L"·"R", 아니면 null. 대문자는 소문자로 바꿔 찾는다const hand = (ch: string): Hand => { const c = ch.toLowerCase(); return LEFT.includes(c) ? "L" : RIGHT.includes(c) ? "R" : null;};let bestLen = 0, bestStart = -1, run = 0, switches = 0;let prev: Hand = null;for (let i = 0; i < s.length; i++) { const h: Hand = hand(s[i]); if (h === null) run = 0; else if (h === prev) run++; else { if (prev !== null) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h;}console.log(`${bestLen}\n${bestLen ? s.slice(bestStart, bestStart + bestLen) : "-"}\n${switches}`);
JavaMain.java · 35 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Main { static final String LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm"; // 영어 글자면 'L'·'R', 아니면 0. 대문자는 소문자로 바꿔 찾는다 static char hand(char ch) { char c = Character.toLowerCase(ch); if (LEFT.indexOf(c) >= 0) return 'L'; if (RIGHT.indexOf(c) >= 0) return 'R'; return 0; } public static void main(String[] args) throws IOException { String s = new BufferedReader(new InputStreamReader(System.in)).readLine(); int bestLen = 0, bestStart = -1, run = 0, switches = 0; char prev = 0; for (int i = 0; i < s.length(); i++) { char h = hand(s.charAt(i)); if (h == 0) run = 0; else if (h == prev) run++; else { if (prev != 0) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h; } System.out.println(bestLen); System.out.println(bestLen > 0 ? s.substring(bestStart, bestStart + bestLen) : "-"); System.out.println(switches); }}
C#Main.cs · 38 行
using System;class Program{ const string Left = "qwertasdfgzxcvb", Right = "yuiophjklnm"; // 영어 글자면 'L'·'R', 아니면 '\0'. 대문자는 소문자로 바꿔 찾는다 static char Hand(char ch) { char c = char.ToLowerInvariant(ch); if (Left.IndexOf(c) >= 0) return 'L'; if (Right.IndexOf(c) >= 0) return 'R'; return '\0'; } static void Main() { string s = Console.ReadLine(); int bestLen = 0, bestStart = -1, run = 0, switches = 0; char prev = '\0'; for (int i = 0; i < s.Length; i++) { char h = Hand(s[i]); if (h == '\0') run = 0; else if (h == prev) run++; else { if (prev != '\0') switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h; } Console.WriteLine(bestLen); Console.WriteLine(bestLen > 0 ? s.Substring(bestStart, bestLen) : "-"); Console.WriteLine(switches); }}
C++main.cpp · 33 行
#include <cctype>#include <iostream>#include <string>const std::string LEFT = "qwertasdfgzxcvb", RIGHT = "yuiophjklnm";// 영어 글자면 'L'·'R', 아니면 0. 대문자는 소문자로 바꿔 찾는다char hand(char ch) { char c = (char)std::tolower((unsigned char)ch); if (LEFT.find(c) != std::string::npos) return 'L'; if (RIGHT.find(c) != std::string::npos) return 'R'; return 0;}int main() { std::string s; std::getline(std::cin, s); if (!s.empty() && s.back() == '\r') s.pop_back(); int bestLen = 0, bestStart = -1, run = 0, switches = 0; char prev = 0; for (int i = 0; i < (int)s.size(); i++) { char h = hand(s[i]); if (h == 0) run = 0; else if (h == prev) run++; else { if (prev != 0) switches++; run = 1; } if (run > bestLen) { bestLen = run; bestStart = i - run + 1; } // 같으면 왼쪽 것 prev = h; } std::cout << bestLen << '\n' << (bestLen > 0 ? s.substr(bestStart, bestLen) : "-") << '\n' << switches << '\n';}
Cmain.c · 35 行
#include <ctype.h>#include <stdio.h>#include <string.h>static char line[100005];/* 영어 글자면 'L'·'R', 아니면 0. strchr는 끝의 '\0'도 찾으니 글자인지 먼저 본다 */static char hand(char ch) { if (!isalpha((unsigned char)ch)) return 0; char c = (char)tolower((unsigned char)ch); return strchr("qwertasdfgzxcvb", c) ? 'L' : 'R';}int main(void) { if (!fgets(line, sizeof line, stdin)) return 0; line[strcspn(line, "\r\n")] = '\0'; /* fgets는 줄바꿈까지 담는다 */ int best_len = 0, best_start = -1, run = 0, switches = 0; char prev = 0; for (int i = 0; line[i]; i++) { char h = hand(line[i]); if (h == 0) run = 0; else if (h == prev) run++; else { if (prev != 0) switches++; run = 1; } if (run > best_len) { best_len = run; best_start = i - run + 1; } /* 같으면 왼쪽 것 */ prev = h; } printf("%d\n", best_len); if (best_len > 0) printf("%.*s\n", best_len, line + best_start); else puts("-"); printf("%d\n", switches); return 0;}
Craykonmain.cray · 62 行
LEFT = "qwertasdfgzxcvb";RIGHT = "yuiophjklnm";// 영어 글자면 "L"·"R", 아니면 "". 대문자는 소문자로 바꿔 찾는다// (있나는 부분 문자열을 찾으니 늘 한 글자만 넘긴다)손(ch){ c = ch.小文字(); もし (LEFT.含む(c)) { 返す "L"; } もし (RIGHT.含む(c)) { 返す "R"; } 返す "";}s = コンソール.行読み();bestLen = 0;bestStart = -1;run = 0; // 지금 글자에서 끝나는 한 손 덩이의 길이switches = 0;prev = ""; // 바로 앞 글자의 손("": 글자가 아님)繰り返す (i = 0; i < s.長さ; i++){ h = 손(s[i]); もし (h == "") { run = 0; } でなければ もし (h == prev) { run++; } でなければ { もし (prev != "") { switches++; } run = 1; } // 글자마다 견주면 줄 끝에서 끝나는 덩이도 놓치지 않는다. >라서 같으면 왼쪽 것 もし (run > bestLen) { bestLen = run; bestStart = i - run + 1; } prev = h;}コンソール.書く(bestLen);もし (bestLen > 0){ コンソール.書く(s.切り出す(bestStart, bestLen));}でなければ{ コンソール.書く("-");}コンソール.書く(switches);