r 行 c 列の盤に 1 から r × c までの数を渦巻き状に埋める。 一行目に r と c が与えられる。 左上のマスに 1 を書き、右へ進みながら次の数を順に書く。 次のマスが盤の外か、すでに数が書かれたマスなら、時計回りに 90 度向きを変えて(右 → 下 → 左 → 上 → 右)その方向のマスに書く。 盤を埋め終えたら一行ずつ出力せよ。 数は r × c の桁数の幅で右寄せにし(足りない桁は前を空白で埋める)、数の間には空白を一つ置く。
入力
1 ≤ r ≤ 50、1 ≤ c ≤ 50
出力
r 行、各行に数 c 個
例 1 · stdin
3 4
stdout
1 2 3 4
10 11 12 5
9 8 7 6
例 2 · stdin
4 3
stdout
1 2 3
10 11 4
9 12 5
8 7 6
main.py
エラー一覧00F8 ↓ · ⇧F8 ↑
入力(stdin)
実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。
$ 準備完了
コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。
ほかの言語では?言語別の解答を見る · 8 言語の解答
盤を 0 で埋めて作る方法に、この問題の最初の落とし穴があります。 Python [[0] * c] * r は同じ行リスト一つを r 回入れるので、一マスに書くと全行のそのマスが変わります。 [[0] * c for _ in range(r)] で行ごとに新しく作ります。 JS・TS new Array(r).fill(new Array(c).fill(0)) も同じ配列一つを全部に入れるので、Array.from({ length: r }, () => new Array(c).fill(0)) と書きます。 Java new int[r][c]、C# new int[r, c]、C のグローバル配列は最初から 0 で、C++ vector(r, vector<int>(c, 0)) は行ごとにコピーします。 Craykon 新リスト(r, 新リスト(c, 0)) もマスごとに別々にコピーして入れます。 向きを時計回りに変えるのは (dy, dx) を (dx, -dy) にすること、つまり二つの値の入れ替えです。 Python dy, dx = dx, -dy、JS・TS [dy, dx] = [dx, -dy]、C# (dy, dx) = (dx, -dy) は一度に変え、C++ は std::swap(dy, dx); dx = -dx; で一時変数なしに書けますが、Java・C・Craykon は一時変数 t = dy; dy = dx; dx = -t; が必要です。 一時変数なしで dy = dx; dx = -dy; と書くと、二行目がすでに変わった dy を使うので斜めに進みます。 幅は r × c の桁数です(例:100 マスなら 3)。 Python str(v).rjust(w)、JS・TS padStart(w)、Java String.format("%" + w + "d", v)、C printf("%*d", w, v)、C++ std::setw(w)、C# PadLeft(w)、Craykon 前埋め(w) でそろえます。
Pythonmain.py · 14 行
r, c = map(int, input().split())grid = [[0] * c for _ in range(r)] # 줄마다 새 목록(같은 목록을 r번 넣지 않게)y, x = 0, 0dy, dx = 0, 1 # 오른쪽으로 시작for k in range(1, r * c + 1): grid[y][x] = k ny, nx = y + dy, x + dx if not (0 <= ny < r and 0 <= nx < c and grid[ny][nx] == 0): dy, dx = dx, -dy # 시계 방향으로 90도: 두 값을 맞바꾸며 부호 하나를 뒤집는다 ny, nx = y + dy, x + dx y, x = ny, nxwidth = len(str(r * c))for row in grid: print(" ".join(str(v).rjust(width) for v in row))
JavaScriptmain.js · 18 行
const [r, c] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);// 줄마다 새 배열(fill에 배열 하나를 주면 모든 줄이 같은 배열이 된다)const grid = Array.from({ length: r }, () => new Array(c).fill(0));let y = 0, x = 0;let dy = 0, dx = 1; // 오른쪽으로 시작for (let k = 1; k <= r * c; k++) { grid[y][x] = k; let ny = y + dy, nx = x + dx; if (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny][nx] === 0)) { [dy, dx] = [dx, -dy]; // 시계 방향으로 90도 ny = y + dy; nx = x + dx; } y = ny; x = nx;}const width = String(r * c).length;console.log(grid.map((row) => row.map((v) => String(v).padStart(width)).join(" ")).join("\n"));
TypeScriptmain.ts · 19 行
import { readFileSync } from "node:fs";const [r, c]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);// 줄마다 새 배열(fill에 배열 하나를 주면 모든 줄이 같은 배열이 된다)const grid: number[][] = Array.from({ length: r }, () => new Array<number>(c).fill(0));let y = 0, x = 0;let dy = 0, dx = 1; // 오른쪽으로 시작for (let k = 1; k <= r * c; k++) { grid[y][x] = k; let ny = y + dy, nx = x + dx; if (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny][nx] === 0)) { [dy, dx] = [dx, -dy]; // 시계 방향으로 90도 ny = y + dy; nx = x + dx; } y = ny; x = nx;}const width: number = String(r * c).length;console.log(grid.map((row) => row.map((v) => String(v).padStart(width)).join(" ")).join("\n"));
JavaMain.java · 35 行
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int r = sc.nextInt(); int c = sc.nextInt(); int[][] grid = new int[r][c]; // 칸마다 0으로 채워져 있다 int y = 0, x = 0; int dy = 0, dx = 1; // 오른쪽으로 시작 for (int k = 1; k <= r * c; k++) { grid[y][x] = k; int ny = y + dy, nx = x + dx; if (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny][nx] == 0)) { int t = dy; // 시계 방향으로 90도: 임시 변수로 맞바꾼다 dy = dx; dx = -t; ny = y + dy; nx = x + dx; } y = ny; x = nx; } String fmt = "%" + String.valueOf(r * c).length() + "d"; StringBuilder out = new StringBuilder(); for (int[] row : grid) { for (int j = 0; j < c; j++) { if (j > 0) out.append(' '); out.append(String.format(fmt, row[j])); } out.append('\n'); } System.out.print(out); }}
C#Main.cs · 40 行
using System;using System.Linq;using System.Text;class Program{ static void Main() { int[] rc = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); int r = rc[0], c = rc[1]; int[,] grid = new int[r, c]; // 칸마다 0으로 채워져 있다 int y = 0, x = 0; int dy = 0, dx = 1; // 오른쪽으로 시작 for (int k = 1; k <= r * c; k++) { grid[y, x] = k; int ny = y + dy, nx = x + dx; if (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny, nx] == 0)) { (dy, dx) = (dx, -dy); // 시계 방향으로 90도: 튜플로 맞바꾼다 ny = y + dy; nx = x + dx; } y = ny; x = nx; } int width = (r * c).ToString().Length; var sb = new StringBuilder(); for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { if (j > 0) sb.Append(' '); sb.Append(grid[i, j].ToString().PadLeft(width)); } sb.Append('\n'); } Console.Write(sb); }}
C++main.cpp · 33 行
#include <iomanip>#include <iostream>#include <string>#include <utility>#include <vector>int main() { int r, c; std::cin >> r >> c; std::vector<std::vector<int>> grid(r, std::vector<int>(c, 0)); // 줄마다 따로 복사된다 int y = 0, x = 0; int dy = 0, dx = 1; // 오른쪽으로 시작 for (int k = 1; k <= r * c; k++) { grid[y][x] = k; int ny = y + dy, nx = x + dx; if (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny][nx] == 0)) { std::swap(dy, dx); // 시계 방향으로 90도: 맞바꾸고 dx = -dx; // 부호 하나를 뒤집는다 ny = y + dy; nx = x + dx; } y = ny; x = nx; } int width = std::to_string(r * c).size(); for (const auto& row : grid) { for (int j = 0; j < c; j++) { if (j > 0) std::cout << ' '; std::cout << std::setw(width) << row[j]; } std::cout << '\n'; }}
Cmain.c · 29 行
#include <stdio.h>int grid[50][50]; // 전역 배열은 0으로 채워져 있다int main(void) { int r, c; scanf("%d %d", &r, &c); int y = 0, x = 0; int dy = 0, dx = 1; // 오른쪽으로 시작 for (int k = 1; k <= r * c; k++) { grid[y][x] = k; int ny = y + dy, nx = x + dx; if (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny][nx] == 0)) { int t = dy; // 시계 방향으로 90도: 임시 변수로 맞바꾼다 dy = dx; dx = -t; ny = y + dy; nx = x + dx; } y = ny; x = nx; } int width = snprintf(NULL, 0, "%d", r * c); // r*c의 자릿수 for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) printf(j ? " %*d" : "%*d", width, grid[i][j]); putchar('\n'); } return 0;}
Craykonmain.cray · 35 行
rc = コンソール.数読み();r = rc[0];c = rc[1];// 새목록에 목록을 주면 줄마다 따로 복사해 넣는다grid = 新リスト(r, 新リスト(c, 0));y = 0;x = 0;dy = 0;dx = 1; // 오른쪽으로 시작繰り返す (k = 1; k <= r * c; k++){ grid[y][x] = k; ny = y + dy; nx = x + dx; もし (!(ny >= 0 && ny < r && nx >= 0 && nx < c && grid[ny][nx] == 0)) { t = dy; // 시계 방향으로 90도: 임시 변수로 맞바꾼다 dy = dx; dx = -t; ny = y + dy; nx = x + dx; } y = ny; x = nx;}width = ("" + r * c).長さ;それぞれ (row の中 grid){ cells = []; それぞれ (v の中 row) { cells.追加(("" + v).前埋め(width)); } コンソール.書く(cells.つなぐ(" "));}