机试:靠谱的车

> 一种奇怪的计费表遇到数字 **4** 会直接跳过,比如: > > ``` > 23 → 25 > 39 → 50 > 399 → 500 > ``` > > 给出一个表面读数(整数 N,1 ≤ N ≤ 10^9),请计算它对应的真实读数(没有跳过 4 的情况)。 > > **输入示例**: > > ``` > 25 > ``` > > **输出示例**: > > ``` > 23 > ``` > > (表面显示 25,实际上走了 23 个单位,因为跳过了 4、14、24…)

1 个回答

  • 柯海
    杯中之物从来不能消愁补过
    ## 思路 显示读数是“十进制外观,但**每一位都跳过 4**”。等价于把显示读数的每一位做如下映射: * 记当前位数字 `d`; * 若 `d > 4`,则有效位值 = `d - 1`;否则 = `d`; * 结果 = 把这些“有效位值”当作 **9 进制** 数字,按位权求和(最高位权最大)。 示例:`25` * 十位 `2` → 有效位 `2`;个位 `5` → 有效位 `4`(因为跳过4,5代表第4个) * 结果 = `2*9 + 4 = 22`;加上从 1 开始/0 开始的口径差异,此题一般**从 0 开始计**,所以就是 23(符合样例)。 > 实操上常见写法:遍历字符串,从高位到低位累计:`ans = ans*9 + (d - (d > 4 ? 1 : 0))`。 * 时间:O(位数) * 空间:O(1) ## Java ```java import java.io.*; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = br.readLine().trim(); // 显示读数,如: 25 long ans = 0; for (int i = 0; i < s.length(); i++) { int d = s.charAt(i) - '0'; int val = d - (d > 4 ? 1 : 0); // 跳过4后的“有效位” ans = ans * 9 + val; } System.out.println(ans); // 25 -> 23, 50 -> 39, 500 -> 399 } } ``` ## Python ```python s = input().strip() ans = 0 for ch in s: d = ord(ch) - ord('0') val = d - (1 if d > 4 else 0) ans = ans * 9 + val print(ans) ``` ### 常见坑 * **不能逐个减去 4、14、24…**(那是线性做法,范围大时慢且易错),必须用“位映射 + 9 进制”。 * 注意用 `long`/`Python int` 防止溢出(N 可达 1e9 甚至更大)。
    发布于 2025-08-13 13:10 •IP属地 山西
    举报
    评论
    收藏