用进制的思想解决问题1145: 有问题的里程表(2)详细代码注释

进制的用途

九进制是只含有九个数字,这里看做是没有4这个数字的九进制数···
逐位*9,以4为界进行累加

问题描述

1145: 有问题的里程表(2)
时间限制: 1 Sec 内存限制: 128 MB
提交: 5771 解决: 3855

题目描述
某辆汽车有一个里程表,该里程表可以显示一个整数,为该车走过的公里数。然而这个里程表有个毛病:它总是从3变到5,而跳过数字4,里程表所有位(个位、 十位、百位等)上的数字都是如此。例如,如果里程表显示15339, 汽车走过1公里之后,该里程表显示15350。

输入
输入一个整数num,表示里程表显示的数值,长度不超过9位,且一定不含整数4。

输出
输出一个整数,表示实际行驶的里程。

样例输入 Copy
150
样例输出 Copy
117

超详细代码注释

#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>

using namespace std;
void real_Dis(int kilo);

int main() {
	int kilo;
	cin >> kilo;
	real_Dis(kilo);

	return 0;
}

// 时间超限
/*
void real_Dis(int kilo) {
	int real_kilo = -1; 
	// int kilo_back = kilo;
	// kilo = -1;
	string str;
	int len;
	int four_pos;
	int i; // 这里的 i 是里程表上的数
	// 这里的 i 从 -1 开始,通过判断 i + 1 中是否含 4 ,来确定下一步的里程表值怎么变化
	for (i = -1; i < kilo;) {
		// 变化是在下一个值 发生的,这里用 i + 1,初始为 -1
		str = to_string(i + 1);
		// to_string 变成字符串
		// stoi 字符串 变成 数字
		// printf("%d", stoi(str));
		// cout << endl;
		// string 中的 find 参数为 string
		//
		//
		// i 不是每次增加 1,i 值,比如 i = 39, 下一个 i 值 会按照里程表变化规则,变成 50
		//	下面展示了 10 进制数,和 9 进制数的对应关系,关键是忽略掉 4

		// 对照一下,找规律
		// 1  2  3  4  5  6  7  8  9     
		// 1  2  3  5  6  7  8  9  10

		// 10 11 12 13 14 15 16 17 18
		// 11 12 13 15 16 17 18 19 20 

		// 19 20 21 22 23 24 25 26 27
		// 21 22 23 25 26 27 28 29 30 

		// 28 29 30 31 32 33 34 35 36
		// 31 32 33 35 36 37 38 39 50 

		// 37 38 39 40 41 42 43 44 45
		// 51 52 53 55 56 57 58 59 60

		// 46
		// 61 62 63 65 66 67 68 69 70
		// 第一行为实际值,第二行为里程表
		if (str.find("4") == string::npos) real_kilo++, i++;
		else {
			// 得到 4 的下标
			four_pos = str.find("4");
			real_kilo++;
			len = str.end() - str.begin();
			i++;
			// 4 现在的位置 10 进制权值与它的下标加起来是 len - 1
			// 因此通过 len - 1 再减去 4 现在的下标
			i += pow(10, (len - 1 - four_pos));
		}
	}
	cout << real_kilo;
}*/



// 当作 9 进制来看时
void real_Dis(int kilo) {
	int ans = 0;
	int len = log10(kilo);
	int temp;
	do {
		// 依次取最高位的数字
		temp = kilo / (pow(10, len));
		// 要讨论此时最高位数字是否大于4
		if (temp < 4) ans += temp * pow(9, len);
		// 大于 4,则要 减去 1 (直接跳过4了,因此 4 没有参与计数)
		// 这里可以想象成 16 进制的 A B C D E F 表示数字的思想,
		// 这里依次用    
		// 1  2  3  5  6  7  8  9  10 // 你会发现这里的 7 等价于 10 进制中的 6,依次 8 等价于 7,………………
		// 来表示 10 进制中的
		// 1  2  3  4  5  6  7  8  9  
		else ans += (temp - 1) * pow(9, len);
		temp = pow(10, len);
		kilo = kilo % temp;
		len--;
	} while (len >= 0);
	cout << ans;
}

什么是理解

永远没有真正的理解吧,只有理解地更深刻了一点

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值