一面楼墙铺满了正方形瓷砖,横向 C 块,纵向 R 排。 广告牌是覆盖 1 块以上整瓷砖的长方形,高 h 排、宽 w 块,都是 1 以上的整数。 广告牌要严格对齐瓷砖的排和列来贴,不能超出墙外,也不旋转。 广告主只买面积 h × w 在 A 以上 B 以下的广告牌。 尺寸 (h, w) 或贴的位置只要有一点不同,就算作不同的情况。 一行给出用空格分开的 R、C、A、B。 按 h 从 1 到 R 的顺序,如果贴高为 h 的广告牌的情况数大于 0,就在一行输出 h 和这个情况数,用一个空格分开。 情况数为 0 的高度不输出。 最后一行输出 "total" 和所有高度的情况数之和,用一个空格分开。 数字只写数字,不加逗号。
输入
1 ≤ R ≤ 500,1 ≤ C ≤ 500,1 ≤ A ≤ B ≤ 250,000(都是整数)
输出
每个有情况的高度一行 "h 情况数",最后一行 "total 总和"
样例 1 · stdin
2 3 2 3
stdout
1 6
2 3
total 9
样例 2 · stdin
3 3 10 20
stdout
total 0
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
高度 h 从 1 到 R、宽度 w 从 1 到 C 两层循环,面积符合时加上贴的位置 (R - h + 1) × (C - w + 1) 种。 在 R 排的墙上贴高 h 的广告牌,最上面一排可以在第 1 排到第 R - h + 1 排,所以不是 R - h。 第一个陷阱是循环的终点。 Python 的 range(1, R + 1) 不包含终点值,写成 range(1, R) 就漏掉了 h = R。 JS、TS、Java、C#、C、C++ 写 for (int h = 1; h <= R; h++),Craykon 写 循环 (h = 1; h <= R; h++),用 <= 把终点包含进去。 C# 的 Enumerable.Range(1, R) 第二个参数不是终点而是个数。 第二,内层循环是宽度,要到 C 为止。 在长宽不同的墙(500 × 1)上把 R 和 C 弄反就会出错。 第三,“A 以上 B 以下”两端都包含,所以是 A <= area && area <= B(Python 可以连写成 A <= area <= B,其他语言会报错(Craykon、Java、C#)或意思不同(JS、TS、C、C++ 会拿前一个比较的结果去和 B 比))。 第四个陷阱是大小。 一个高度的情况数在 int 范围内,但 500 × 500 的墙上总和约为 1.6×10^10,所以要加到 C/C++ 的 long long 或 Java/C# 的 long 里。 JS、TS、Craykon 的数在 2^53 以内是精确的,Python 的 int 不会溢出。
Pythonmain.py · 11 行
R, C, A, B = map(int, input().split())total = 0for h in range(1, R + 1): # range의 끝은 들어가지 않는다: R까지 돌려면 R + 1 count = 0 for w in range(1, C + 1): if A <= h * w <= B: count += (R - h + 1) * (C - w + 1) # 위쪽 줄 R-h+1가지 × 왼쪽 칸 C-w+1가지 if count > 0: print(h, count) total += countprint("total", total)
JavaScriptmain.js · 14 行
const [R, C, A, B] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const out = [];let total = 0; // 최대 약 1.6×10^10: 2^53 안이라 Number로 정확하다for (let h = 1; h <= R; h++) { let count = 0; for (let w = 1; w <= C; w++) { const area = h * w; if (A <= area && area <= B) count += (R - h + 1) * (C - w + 1); } if (count > 0) out.push(`${h} ${count}`); total += count;}out.push(`total ${total}`);console.log(out.join("\n"));
TypeScriptmain.ts · 15 行
import { readFileSync } from "node:fs";const [R, C, A, B]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);const out: string[] = [];let total = 0; // 최대 약 1.6×10^10: 2^53 안이라 number로 정확하다for (let h = 1; h <= R; h++) { let count = 0; for (let w = 1; w <= C; w++) { const area: number = h * w; if (A <= area && area <= B) count += (R - h + 1) * (C - w + 1); } if (count > 0) out.push(`${h} ${count}`); total += count;}out.push(`total ${total}`);console.log(out.join("\n"));
JavaMain.java · 21 行
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int R = sc.nextInt(), C = sc.nextInt(), A = sc.nextInt(), B = sc.nextInt(); StringBuilder out = new StringBuilder(); long total = 0; // 최대 약 1.6×10^10: int로는 넘친다 for (int h = 1; h <= R; h++) { long count = 0; for (int w = 1; w <= C; w++) { int area = h * w; if (A <= area && area <= B) count += (long) (R - h + 1) * (C - w + 1); } if (count > 0) out.append(h).append(' ').append(count).append('\n'); total += count; } out.append("total ").append(total).append('\n'); System.out.print(out); }}
C#Main.cs · 27 行
using System;using System.Linq;using System.Text;class Program{ static void Main() { int[] v = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); int R = v[0], C = v[1], A = v[2], B = v[3]; var out_ = new StringBuilder(); long total = 0; // 최대 약 1.6×10^10: int로는 넘친다 for (int h = 1; h <= R; h++) { long count = 0; for (int w = 1; w <= C; w++) { int area = h * w; if (A <= area && area <= B) count += (long)(R - h + 1) * (C - w + 1); } if (count > 0) out_.Append(h).Append(' ').Append(count).Append('\n'); total += count; } out_.Append("total ").Append(total).Append('\n'); Console.Write(out_); }}
C++main.cpp · 17 行
#include <iostream>int main() { int R, C, A, B; std::cin >> R >> C >> A >> B; long long total = 0; // 최대 약 1.6×10^10: int로는 넘친다 for (int h = 1; h <= R; h++) { long long count = 0; for (int w = 1; w <= C; w++) { int area = h * w; if (A <= area && area <= B) count += (long long)(R - h + 1) * (C - w + 1); } if (count > 0) std::cout << h << ' ' << count << '\n'; total += count; } std::cout << "total " << total << '\n';}
Cmain.c · 18 行
#include <stdio.h>int main(void) { int R, C, A, B; scanf("%d %d %d %d", &R, &C, &A, &B); long long total = 0; /* 최대 약 1.6×10^10: int로는 넘친다 */ for (int h = 1; h <= R; h++) { long long count = 0; for (int w = 1; w <= C; w++) { int area = h * w; if (A <= area && area <= B) count += (long long)(R - h + 1) * (C - w + 1); } if (count > 0) printf("%d %lld\n", h, count); total += count; } printf("total %lld\n", total); return 0;}
Craykonmain.cray · 25 行
v = 控制台.读数字();R = v[0];C = v[1];A = v[2];B = v[3];total = 0; // 최대 약 1.6×10^10: 2^53 안이라 정확하다循环 (h = 1; h <= R; h++){ count = 0; 循环 (w = 1; w <= C; w++) { area = h * w; 如果 (A <= area && area <= B) { // 위쪽 줄 R-h+1가지 × 왼쪽 칸 C-w+1가지 count += (R - h + 1) * (C - w + 1); } } 如果 (count > 0) { 控制台.输出(h + " " + count); } total += count;}控制台.输出("total " + total);