1 ≤ n ≤ 10,2 ≤ b_i ≤ 60,0 ≤ d_i < b_i,-10^12 ≤ t ≤ 10^12(都是整数)
输出
第一行:n 个轮子的格;第二行:翻过的次数(向后为负)
样例 1 · stdin
3
24 60 60
23 59 50
15
stdout
0 0 5
1
样例 2 · stdin
2
7 3
0 1
-5
stdout
5 2
-1
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 8 种语言题解
从最右边的轮子开始,把进来的值 s = d +(传进来的值)分成格 s mod b 和传给左边的商即可。 向后转时 s 是负数,各语言的 % 和 / 就不同了。 Python 的 %、// 是向下取整除法,格总在 0 ~ b-1,商也是向下取整的值(-4 // 3 == -2),直接就对。 C、C++、Java、C#、JS、TS、Craykon 的 % 跟随被除数的符号(-4 % 3 == -1),C、C++、Java、C# 的整数 /、JS/TS 的 Math.trunc(s / b) 和 Craykon 的 数学.商 向 0 截断(-4 / 3 == -1),于是格变成负数,借位也少了一个。 JS、TS、Craykon 的 / 会除出小数(-4 / 3 == -1.333…),不能直接当商用。 先用 (s % b + b) % b 修正格,再用 (s - 格) / b 求商(正好整除),或者在 Java 里用 Math.floorMod、Math.floorDiv。 只修正格、商仍用向 0 截断的除法也是常见错误。 第二个陷阱是大小。 t 可达 10^12,C/C++ 需要 long long,Java/C# 需要 long,放进 int 会溢出。 JS、TS、Craykon 的数在 2^53(约 9×10^15)以内是精确的,所以 t 本身没问题。 但如果把整个计数器换成一个数来算,轮子格数的乘积可达 60^10(约 6×10^17),超过 2^53,低位就会出错。 逐个轮子用余数和商传下去,在任何语言里数值都停留在 t 附近。 Python 的 int(s / b) 也是在浮点除法后向 0 截断,是同一个陷阱。
Pythonmain.py · 14 行
n = int(input())b = list(map(int, input().split()))d = list(map(int, input().split()))t = int(input())# 오른쪽 바퀴부터: 이 바퀴에 들어온 값 s를 칸(나머지)과 왼쪽으로 넘길 값(몫)으로 나눈다# Python의 %와 //는 내림 나눗셈이라 s가 음수여도 칸은 0 ~ b-1, 몫은 아래로 내린 값이다carry = tfor i in range(n - 1, -1, -1): s = d[i] + carry d[i] = s % b[i] carry = s // b[i]print(*d)print(carry) # 맨 왼쪽 바퀴에서도 넘친 값 = 계수기 전체가 넘어간 횟수
JavaScriptmain.js · 13 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const b = lines[1].trim().split(/\s+/).map(Number);const d = lines[2].trim().split(/\s+/).map(Number);let carry = Number(lines[3]); // 10^12는 2^53 안이라 Number로 정확하다// JS의 %는 나누어지는 수의 부호를 따른다(-7 % 3 === -1) → b를 더해 다시 나눈다for (let i = n - 1; i >= 0; i--) { const s = d[i] + carry; d[i] = ((s % b[i]) + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫}console.log(d.join(" ") + "\n" + carry);
TypeScriptmain.ts · 14 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const b: number[] = lines[1].trim().split(/\s+/).map(Number);const d: number[] = lines[2].trim().split(/\s+/).map(Number);let carry: number = Number(lines[3]); // 10^12는 2^53 안이라 number로 정확하다// TS(JS)의 %는 나누어지는 수의 부호를 따른다(-7 % 3 === -1) → b를 더해 다시 나눈다for (let i = n - 1; i >= 0; i--) { const s: number = d[i] + carry; d[i] = ((s % b[i]) + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫}console.log(d.join(" ") + "\n" + carry);
JavaMain.java · 24 行
import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] b = new int[n]; long[] d = new long[n]; for (int i = 0; i < n; i++) b[i] = sc.nextInt(); for (int i = 0; i < n; i++) d[i] = sc.nextLong(); long carry = sc.nextLong(); // 10^12: int로는 넘친다 // Java의 %와 /는 0 쪽으로 버린다(-7 % 3 == -1) → Math.floorMod·floorDiv는 내림으로 나눈다 for (int i = n - 1; i >= 0; i--) { long s = d[i] + carry; d[i] = Math.floorMod(s, (long) b[i]); carry = Math.floorDiv(s, (long) b[i]); } StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) out.append(i > 0 ? " " : "").append(d[i]); out.append('\n').append(carry).append('\n'); System.out.print(out); }}
C#Main.cs · 23 行
using System;using System.Linq;class Program{ static void Main() { int n = int.Parse(Console.ReadLine()); int[] b = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); long[] d = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToArray(); long carry = long.Parse(Console.ReadLine().Trim()); // 10^12: int로는 넘친다 // C#의 %는 나누어지는 수의 부호를 따른다(-7 % 3 == -1) → b를 더해 다시 나눈다 for (int i = n - 1; i >= 0; i--) { long s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫 } Console.WriteLine(string.Join(" ", d)); Console.WriteLine(carry); }}
C++main.cpp · 21 行
#include <iostream>#include <vector>int main() { int n; std::cin >> n; std::vector<long long> b(n), d(n); for (auto& x : b) std::cin >> x; for (auto& x : d) std::cin >> x; long long carry; // t는 10^12까지: int로는 넘친다 std::cin >> carry; // C++의 %는 0 쪽으로 버린 나눗셈의 나머지라 음수가 나올 수 있다 → b를 더해 다시 나눈다 for (int i = n - 1; i >= 0; i--) { long long s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i]; // s - 칸은 b로 딱 나누어떨어진다: 내림 몫 } for (int i = 0; i < n; i++) std::cout << (i ? " " : "") << d[i]; std::cout << '\n' << carry << '\n';}
Cmain.c · 20 行
#include <stdio.h>int main(void) { int n, b[10]; long long d[10], carry; /* t는 10^12까지: int로는 넘친다 */ scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &b[i]); for (int i = 0; i < n; i++) scanf("%lld", &d[i]); scanf("%lld", &carry); /* C의 %는 0 쪽으로 버린 나눗셈의 나머지라 음수가 나올 수 있다 → b를 더해 다시 나눈다 */ for (int i = n - 1; i >= 0; i--) { long long s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i]; /* s - 칸은 b로 딱 나누어떨어진다: 내림 몫 */ } for (int i = 0; i < n; i++) printf(i ? " %lld" : "%lld", d[i]); printf("\n%lld\n", carry); return 0;}
Craykonmain.cray · 15 行
n = 控制台.读行().转数字();b = 控制台.读数字();d = 控制台.读数字();carry = 控制台.读行().转数字(); // 10^12는 2^53 안이라 정확하다// 크레이콘의 %도 나누어지는 수의 부호를 따른다(-7 % 3 == -1) → b를 더해 다시 나눈다// 수학.몫은 0 쪽으로 버리니, 내림 몫은 (s - 칸) / b로 구한다(딱 나누어떨어진다)循环 (i = n - 1; i >= 0; i--){ s = d[i] + carry; d[i] = (s % b[i] + b[i]) % b[i]; carry = (s - d[i]) / b[i];}控制台.输出(d.连接(" "));控制台.输出(carry);