UVa 11121 Base -2 (数论 & -2进制 & 补足思想)

11121 - Base -2

Time limit: 3.000 seconds

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=2062


(参考《Hacker's Delight》)

The creator of the universe works in mysterious ways. But
he uses a base ten counting system and likes round numbers.

Scott Adams

Everyone knows about base-2 (binary) integers and base-10 (decimal) integers, but what about base -2? An integer n written in base -2 is a sequence of digits  (b i) , writen right-to-left. Each of which is either 0 or 1 (no negative digits!), and the following equality must hold.

n = b0 + b1(-2) + b2(-2)2 + b3(-2)3 + ...

The cool thing is that every integer (including the negative ones) has a unique base--2 representation, with no minus sign required. Your task is to find this representation.

Input
The first line of input gives the number of cases, N (at most 10000). N test cases follow. Each one is a line containing a decimal integer in the range from  -1,000,000,000  to  1,000,000,000 .

Output
For each test case, output one line containing "Case #x:" followed by the same integer, written in base -2 with no leading zeros.

Sample Input      Output for Sample Input

4
1
7
-2
0                         
Case #1: 1
Case #2: 11011
Case #3: 10

Case #4: 0


思路:

一种思路是:不妨拿我们在算二进制中做的那样,只做下小修改就行。

另一种思路有点巧妙:如果二进制对应那一位p是1,则将n+=1<<(p+1),最终n化为了正规的二进制。(速度更快)


way 1:

/*0.045s*/

#include <cstdio>

int array[40];

int main()
{
	int T, n, i, j, CASE =0 0;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		printf("Case #%d: ", ++CASE);
		if (n == 0)  puts("0");
		else
		{
			i = 0;
			while (n)
			{
				array[i++] = n & 1;
				n = (n - (n & 1)) / -2;
			}
			for (j = i - 1; j >= 0; j--)
				printf("%d", array[j]);
			putchar(10);
		}
	}
}


way 2:

/*0.019s*/

#include<cstdio>
#include<cstdlib>
typedef long long ll;
const ll one = 1;

int main()
{
	ll n, bit;///非常不巧需要1<<32,所以用long long
	int T, cas = 0, p;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%lld", &n);
		printf("Case #%d: ", ++cas);
		if (n == 0)
		{
			puts("0");
			continue;
		}
		///n转化成2进制意义下的n
		p = (n > 0 ? 1 : 0);///起始
		n = abs(n);
		bit = one << p;
		while (p <= 32)
		{
			if (bit & n)
				n += one << (p + 1);///修正
			p += 2;
			bit = one << p;
		}
		///去前导零
		for (bit = one << 31; (bit & n) == 0; bit >>= 1)
			;
		///求二进制
		while (bit)
		{
			putchar(bit & n ? '1' : '0');
			bit >>= 1;
		}
		putchar(10);
	}
	return 0;
}


### 数论中模幂运算的概念和实现方法 #### 模幂运算的基本概念 模幂运算是数论中的一个重要概念,用于计算一个数的幂对另一个数取模的结果。其数学表示为 \( a^b \mod n \),其中 \( a \) 是底数,\( b \) 是指数,\( n \) 是模数[^1]。这种运算在计算机科学和密码学中具有广泛应用,尤其是在处理大数运算时,可以有效避免数值溢出问题。 #### 模幂运算的核心思想 模幂运算的核心思想是通过分治法将大指数分解为较小的部分进行逐步计算。这种方法不仅提高了计算效率,还降低了内存需求。具体而言,模幂运算利用了以下两个性质: 1. \( (a \cdot b) \mod n = [(a \mod n) \cdot (b \mod n)] \mod n \) 2. \( a^{2k} \mod n = (a^k \mod n)^2 \mod n \)[^2] #### 模幂运算的实现算法 模幂运算可以通过迭代或递归的方式实现。以下是基于迭代的快速幂算法实现,该算法的时间复杂度为 \( O(\log b) \)。 ```c #include &lt;stdio.h&gt; // 快速幂算法实现模幂运算 int modularExponentiation(int base, int exponent, int modulus) { int result = 1; // 初始化结果为1 base = base % modulus; // 确保底数小于模数 while (exponent &gt; 0) { if (exponent &amp; 1) { // 如果指数的最低位为1 result = (result * base) % modulus; } base = (base * base) % modulus; // 底数平方 exponent &gt;&gt;= 1; // 指数右移一位 } return result; } int main() { int a, m, n; printf(&quot;请输入底数a、指数m和模数n: &quot;); scanf(&quot;%d%d%d&quot;, &amp;a, &amp;m, &amp;n); int result = modularExponentiation(a, m, n); printf(&quot;结果: %d\n&quot;, result); return 0; } ``` 上述代码实现了模幂运算的功能,使用了快速幂算法来高效计算 \( a^m \mod n \)[^3]。通过逐位检查指数的二进制表示,算法能够以对数时间完成计算。 #### 模幂运算的应用场景 模幂运算广泛应用于密码学领域,例如 RSA 加密算法中的密钥生成和加密解密过程。此外,在分布式计算和量子计算机理论逐渐成熟的背景下,模幂运算的安全性也受到了广泛关注[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值