import sysMOVES = {"U": (0, 1), "D": (0, -1), "L": (-1, 0), "R": (1, 0)}lines = sys.stdin.read().split("\n")n = int(lines[0])black = set() # 검은 타일의 자리 (x, y)x = y = 0for line in lines[1:n + 1]: d, k = line.split() dx, dy = MOVES[d] for _ in range(int(k)): x += dx y += dy if (x, y) in black: black.remove((x, y)) # 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 break black.add((x, y)) # 흰 타일: 검은색으로 뒤집고 이어 간다print(len(black))print(x, y)
JavaScriptmain.js · 23 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const MOVES = { U: [0, 1], D: [0, -1], L: [-1, 0], R: [1, 0] };// 배열 [x, y]는 내용이 같아도 다른 원소로 치므로, 문자열 "x,y"를 넣는다const black = new Set();let x = 0;let y = 0;for (let i = 1; i <= n; i++) { const [d, k] = lines[i].trim().split(" "); const [dx, dy] = MOVES[d]; for (let step = 0; step < Number(k); step++) { x += dx; y += dy; const key = `${x},${y}`; if (black.has(key)) { black.delete(key); // 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 break; } black.add(key); // 흰 타일: 검은색으로 뒤집고 이어 간다 }}console.log(black.size);console.log(`${x} ${y}`);
TypeScriptmain.ts · 25 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const MOVES: Record<string, [number, number]> = { U: [0, 1], D: [0, -1], L: [-1, 0], R: [1, 0] };// 배열 [x, y]는 내용이 같아도 다른 원소로 치므로, 문자열 "x,y"를 넣는다const black = new Set<string>();let x = 0;let y = 0;for (let i = 1; i <= n; i++) { const [d, k]: string[] = lines[i].trim().split(" "); const [dx, dy]: [number, number] = MOVES[d]; for (let step = 0; step < Number(k); step++) { x += dx; y += dy; const key: string = `${x},${y}`; if (black.has(key)) { black.delete(key); // 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 break; } black.add(key); // 흰 타일: 검은색으로 뒤집고 이어 간다 }}console.log(black.size);console.log(`${x} ${y}`);
JavaMain.java · 40 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashSet;import java.util.Set;public class Main { // record는 equals와 hashCode를 값으로 만들어 주므로 집합에 그대로 넣을 수 있다 record Tile(int x, int y) {} public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine().trim()); Set<Tile> black = new HashSet<>(); int x = 0, y = 0; for (int i = 0; i < n; i++) { String[] parts = in.readLine().trim().split(" "); int dx = 0, dy = 0; switch (parts[0]) { case "U" -> dy = 1; case "D" -> dy = -1; case "L" -> dx = -1; default -> dx = 1; } int k = Integer.parseInt(parts[1]); for (int step = 0; step < k; step++) { x += dx; y += dy; Tile tile = new Tile(x, y); if (black.contains(tile)) { black.remove(tile); // 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 break; } black.add(tile); // 흰 타일: 검은색으로 뒤집고 이어 간다 } } System.out.println(black.size()); System.out.println(x + " " + y); }}
C#Main.cs · 39 行
using System;using System.Collections.Generic;class Program{ static void Main() { int n = int.Parse(Console.ReadLine().Trim()); // 튜플 (x, y)는 값이 같으면 같은 원소다 var black = new HashSet<(int, int)>(); int x = 0, y = 0; for (int i = 0; i < n; i++) { string[] parts = Console.ReadLine().Trim().Split(' '); int dx = 0, dy = 0; switch (parts[0]) { case "U": dy = 1; break; case "D": dy = -1; break; case "L": dx = -1; break; default: dx = 1; break; } int k = int.Parse(parts[1]); for (int step = 0; step < k; step++) { x += dx; y += dy; if (black.Contains((x, y))) { black.Remove((x, y)); // 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 break; } black.Add((x, y)); // 흰 타일: 검은색으로 뒤집고 이어 간다 } } Console.WriteLine(black.Count); Console.WriteLine($"{x} {y}"); }}
C++main.cpp · 36 行
#include <iostream>#include <set>#include <utility>using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; // pair는 값으로 견주므로 std::set에 그대로 넣을 수 있다 set<pair<int, int>> black; int x = 0, y = 0; for (int i = 0; i < n; i++) { char d; int k; cin >> d >> k; int dx = 0, dy = 0; if (d == 'U') dy = 1; else if (d == 'D') dy = -1; else if (d == 'L') dx = -1; else dx = 1; for (int step = 0; step < k; step++) { x += dx; y += dy; auto it = black.find({x, y}); if (it != black.end()) { black.erase(it); // 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 break; } black.insert({x, y}); // 흰 타일: 검은색으로 뒤집고 이어 간다 } } cout << black.size() << '\n' << x << ' ' << y << '\n'; return 0;}
Cmain.c · 49 行
#include <stdio.h>#define MAXSTEPS 9000/* C에는 집합이 없다. 검은 타일의 자리를 배열에 모아 두고 처음부터 찾는다. 걸음이 많아야 9,000번이라 검은 타일도 9,000개를 넘지 않는다. */static int bx[MAXSTEPS], by[MAXSTEPS];static int count = 0;/* (x, y)가 든 칸 번호를 돌려준다. 없으면 -1 */static int find(int x, int y) { for (int i = 0; i < count; i++) { if (bx[i] == x && by[i] == y) return i; } return -1;}int main(void) { int n; scanf("%d", &n); int x = 0, y = 0; for (int i = 0; i < n; i++) { char d; int k; scanf(" %c %d", &d, &k); int dx = 0, dy = 0; if (d == 'U') dy = 1; else if (d == 'D') dy = -1; else if (d == 'L') dx = -1; else dx = 1; for (int step = 0; step < k; step++) { x += dx; y += dy; int at = find(x, y); if (at >= 0) { /* 검은 타일: 마지막 칸을 그 자리로 옮겨 지우고, 남은 걸음을 버린다 */ count--; bx[at] = bx[count]; by[at] = by[count]; break; } bx[count] = x; /* 흰 타일: 검은색으로 뒤집고 이어 간다 */ by[count] = y; count++; } } printf("%d\n%d %d\n", count, x, y); return 0;}
Craykonmain.cray · 43 行
n = コンソール.行読み().数に();// 사전의 열쇠를 집합처럼 쓴다. 자리는 문자열 "x,y"로 바꿔 넣는다black = 辞書();x = 0;y = 0;繰り返す (i = 0; i < n; i++){ parts = コンソール.行読み().空白除去().分ける(); dx = 0; dy = 0; 選択 (parts[0]) { 場合 "U": dy = 1; 抜ける; 場合 "D": dy = -1; 抜ける; 場合 "L": dx = -1; 抜ける; それ以外: dx = 1; 抜ける; } k = parts[1].数に(); 繰り返す (step = 0; step < k; step++) { x += dx; y += dy; key = x + "," + y; もし (black.含む(key)) { // 검은 타일: 흰색으로 뒤집고 남은 걸음을 버린다 black.取り除く(key); 抜ける; } // 흰 타일: 검은색으로 뒤집고 이어 간다 black[key] = 真; }}コンソール.書く(black.個数);コンソール.書く(x + " " + y);