例题7-1 除法

本文介绍了一种通过枚举算法解决特定数学问题的方法,即找出所有可能的数字排列使得一个分数等于给定的整数值。文章提供了一个C++实现示例,并解释了如何利用sprintf函数和排序技巧来验证数字排列的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

输入正整数n,按从小到大的顺序输出所有形如abcde / fghij = n的表达式,其中a~j恰好为数字0~9的一个排列(可以有前导0),2≤n≤79

input:

62

output:

79546 / 01293 = 62

94736 / 01528 = 62


书上示例:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int main() {
	int n, kase = 0;
	char buf[99];
	while (scanf("%d", &n) == 1 && n)
	{
		int cnt = 0;
		if (kase++) 
			printf("\n");
		for (int fghij = 1234; ; fghij++) 
		{
			int abcde = fghij * n;
			sprintf(buf, "%05d%05d", abcde, fghij);	
			if (strlen(buf) > 10) break;
			sort(buf, buf + 10);
			bool ok = true;
			for (int i = 0; i < 10; i++)
				if (buf[i] != '0' + i) ok = false;
			if (ok) {
				cnt++;
				printf("%05d / %05d = %d\n", abcde, fghij, n);
			}
		}
		if (!cnt) printf("There are no solutions for %d.\n", n);
	}
	return 0;
}


枚举,题上求除法,算法可用乘法反求结果,避免出现小数。fghij从1234开始(01234),直到abcde fghij的总长>10停止枚举,中间用排序,方便 重复 数字的检测


int sprintf( char *buffer, const char *format, [argument] … );

bufferchar型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument].. .:可选参数,可以是任何类型的数据。

%nd 表示输出的整型宽度至少为n位,右对齐,%5d即宽度至少为5位,位数大于5则输出实际位数
%0nd 表示输出的整型宽度至少为n位,不足n位用0填充


### 原码与补码除法运算示例 #### 背景说明 在计算机组成原理中,原码和补码是两种重要的编码方式。其中,**原码**是最直观的表示形式,而**补码**则被广泛应用于实际计算中,尤其是在涉及负数的情况下[^1]。 对于 **原码除法** 和 **补码除法** 的实现,两者的核心差异在于如何处理符号位以及数值部分的操作逻辑。以下是具体的例子及其解析: --- #### 示例题目:已知两个有符号整数 X = -79 (十进制),Y = 5 (十进制),求它们通过补码除法的结果 Z = X / Y。 ##### 步骤分析 1. **转换为二进制补码** 将给定的十进制数分别转化为对应的8位二进制补码形式。 对于 X = -79: - 原码为 `11001111` (最高位为符号位,“1”代表负号) - 反码为 `10110000` (取反操作) - 补码为 `10110001` (反码加1) 对于 Y = 5: - 原码、反码、补码均为 `00000101` 2. **初始化变量** 设商初值 Q = 0(初始状态),余数 R 初始等于被除数 X 的绝对值 |X| 的补码形式。 3. **执行加减交替法** 使用补码除法规则中的加减交替法进行逐位比较并更新商和余数。具体过程如下表所示: | 步骤编号 | 当前余数R | 商Q变化 | 操作描述 | |----------|--------------------|---------------|------------------------------------------------------------------------| | 初始化 | 10110001 | 0 | 设置当前余数为被除数的补码 | | 第一步 | 10110001 + 00000101=10110110 | 左移一位得0 | 加上除数的补码后仍小于零,故不借位 | | 第二步 | ... | 更新后的结果...| 继续重复上述流程直至完成全部比特位 | 最终得出完整的商和可能存在的剩余误差项。 4. **验证结果** 计算完成后需再次确认所得结果是否满足原始定义下的精度需求,并考虑溢出情况等问题。 --- ```python def complement_division(dividend, divisor): """ Perform division using two's complement representation. Args: dividend (int): The number to be divided. divisor (int): The number by which we divide. Returns: tuple: Quotient and remainder as integers. """ # Convert inputs into binary strings with sign bit included n_bits = max(len(bin(abs(dividend))[2:]), len(bin(abs(divisor))[2:])) + 1 def twos_complement(x, num_bits=n_bits): """Compute the two’s complement of int value.""" mask = (1 << num_bits) - 1 return ~x & mask if x < 0 else x divd_cplmnt = twos_complement(dividend) dsr_cplmnt = twos_complement(divisor) quotient = 0 temp_remainder = abs(dividend).to_bytes((n_bits + 7) // 8, 'big', signed=True)[::-1] for _ in range(n_bits - 1): # Shift left one position effectively multiplying current partial result by 2 shifted_temp_rem = ((temp_remainder[-1] >> 7) * (-dsr_cplmnt)) ^ \ (((temp_remainder[:-1].ljust(8, b'\x00') + bytes([temp_remainder[-1]]))) << 1) carry_out = bool(shifted_temp_rem >= (1 << (n_bits - 1))) new_val = shifted_temp_rem % (1 << n_bits) # Update based on whether there was a borrow or not during subtraction phase above if not carry_out: quotient |= (1 << (_)) temp_remainder = new_val.to_bytes(((new_val.bit_length() + 7)//8), byteorder='little') final_quo_sign_adjustment = -(dividend//abs(divisor)) if dividend*divisor<0 else dividend//abs(divisor) return final_quo_sign_adjustment , from_twos_comp(temp_remainder,n_bits) print(complement_division(-79,5)) ``` --- ### 结果总结 经过以上步骤可以得到最终答案Z=-15,其余数为4。这表明当采用补码方式进行此类复杂运算时能够有效简化硬件设计同时保持较高的准确性[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值