把每周星期日的日期从 1 - w 开始每次加 7(0 及以下表示上个月的格子),就不必另外计算行数。 每次加 7 的循环:Python range(1 - w, n + 1, 7)(终点 n + 1 不包含),C 系、JS、TS for (s = 1 - w; s <= n; s += 7),Craykon 循环 (s = 1 - w; s <= n; s += 7)。 常见陷阱有三个。 Python 中把终点写成 n,当 n 日是星期日时会漏掉最后一周。 用 (w + n) / 7 + 1 计算行数,恰好在星期六结束的月份会多出一个空行。 下个月的星期是 (w + n) % 7(w + n - 1 是最后一天的星期)。 填格子只需一个三元运算:Python f"{d:2d}" if 1 <= d <= n else " "(条件在中间),其他语言 条件 ? 值 : 值。 右对齐:Python f"{d:2d}",JS/TS String(d).padStart(2)(padEnd 是左对齐,会错),Java String.format("%2d", d),C# d.ToString().PadLeft(2),C printf("%2d"),C++ std::setw(2),Craykon ("" + d).左填充(2)。
Pythonmain.py · 12 行
k, w = map(int, input().split())lengths = list(map(int, input().split()))months = []for n in lengths: lines = [] # 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for start in range(1 - w, n + 1, 7): cells = [f"{d:2d}" if 1 <= d <= n else " " for d in range(start, start + 7)] lines.append(" ".join(cells).rstrip()) months.append("\n".join(lines)) w = (w + n) % 7 # 다음 달 1일의 요일print("\n\n".join(months))
JavaScriptmain.js · 15 行
const [, first, ...lengths] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let w = first;const months = [];for (const n of lengths) { const lines = []; // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for (let start = 1 - w; start <= n; start += 7) { const cells = []; for (let d = start; d < start + 7; d++) cells.push(d >= 1 && d <= n ? String(d).padStart(2) : " "); lines.push(cells.join(" ").trimEnd()); } months.push(lines.join("\n")); w = (w + n) % 7; // 다음 달 1일의 요일}console.log(months.join("\n\n"));
TypeScriptmain.ts · 16 行
import { readFileSync } from "node:fs";const [, first, ...lengths]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);let w: number = first;const months: string[] = [];for (const n of lengths) { const lines: string[] = []; // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for (let start = 1 - w; start <= n; start += 7) { const cells: string[] = []; for (let d = start; d < start + 7; d++) cells.push(d >= 1 && d <= n ? String(d).padStart(2) : " "); lines.push(cells.join(" ").trimEnd()); } months.push(lines.join("\n")); w = (w + n) % 7; // 다음 달 1일의 요일}console.log(months.join("\n\n"));
JavaMain.java · 25 行
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int k = sc.nextInt(); int w = sc.nextInt(); StringBuilder out = new StringBuilder(); for (int m = 0; m < k; m++) { int n = sc.nextInt(); if (m > 0) out.append('\n'); // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for (int start = 1 - w; start <= n; start += 7) { StringBuilder line = new StringBuilder(); for (int d = start; d < start + 7; d++) { if (d > start) line.append(' '); line.append(d >= 1 && d <= n ? String.format("%2d", d) : " "); } out.append(line.toString().stripTrailing()).append('\n'); } w = (w + n) % 7; // 다음 달 1일의 요일 } System.out.print(out); }}
C#Main.cs · 30 行
using System;using System.Collections.Generic;using System.Text;class Program{ static void Main() { string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int w = int.Parse(first[1]); string[] lengths = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); var months = new List<string>(); foreach (string s in lengths) { int n = int.Parse(s); var lines = new List<string>(); // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for (int start = 1 - w; start <= n; start += 7) { var cells = new List<string>(); for (int d = start; d < start + 7; d++) cells.Add(d >= 1 && d <= n ? d.ToString().PadLeft(2) : " "); lines.Add(string.Join(" ", cells).TrimEnd()); } months.Add(string.Join("\n", lines)); w = (w + n) % 7; // 다음 달 1일의 요일 } Console.WriteLine(string.Join("\n\n", months)); }}
C++main.cpp · 23 行
#include <iomanip>#include <iostream>#include <string>int main() { int k, w; std::cin >> k >> w; for (int m = 0; m < k; m++) { int n; std::cin >> n; if (m > 0) std::cout << '\n'; // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for (int start = 1 - w; start <= n; start += 7) { for (int d = start; d < start + 7 && d <= n; d++) { if (d > start) std::cout << ' '; if (d >= 1) std::cout << std::setw(2) << d; else std::cout << " "; } std::cout << '\n'; } w = (w + n) % 7; // 다음 달 1일의 요일 }}
Cmain.c · 23 行
#include <stdio.h>int main(void) { int k, w; scanf("%d %d", &k, &w); for (int m = 0; m < k; m++) { int n; scanf("%d", &n); if (m > 0) putchar('\n'); // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) for (int start = 1 - w; start <= n; start += 7) { // 마지막 날 뒤 칸은 줄 끝 빈칸이라 찍지 않는다 for (int d = start; d < start + 7 && d <= n; d++) { if (d > start) putchar(' '); if (d >= 1) printf("%2d", d); else printf(" "); } putchar('\n'); } w = (w + n) % 7; // 다음 달 1일의 요일 } return 0;}
Craykonmain.cray · 23 行
kw = 控制台.读数字();k = kw[0];w = kw[1];lengths = 控制台.读数字();循环 (m = 0; m < k; m++){ n = lengths[m]; 如果 (m > 0) { 控制台.输出(""); } // 한 주의 일요일 날짜: 1 - w부터 7씩 건너뛴다(0 이하면 지난달 칸) 循环 (start = 1 - w; start <= n; start += 7) { cells = []; 循环 (d = start; d < start + 7; d++) { cells.添加(d >= 1 && d <= n ? ("" + d).左填充(2) : " "); } 控制台.输出(cells.连接(" ")); } w = (w + n) % 7; // 다음 달 1일의 요일}