UVa 11121 - Base -2 负进制的转化和推广
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2062
題目大意就是給你一個(gè)-1000,000,000到1000,000,000的數(shù)轉(zhuǎn)化成-2進(jìn)制。
看到-2就想到了2進(jìn)制,原先想兩位兩位地考慮,然后看成2進(jìn)制的,接下來求一下方程的正數(shù)解就行了,然后將那些數(shù)全都轉(zhuǎn)化成0和1,后來又發(fā)現(xiàn)。。每項(xiàng)之間差了4倍,頓時(shí)就不行了。接著想著是不是能將 (-2)^k 和 2^k 聯(lián)系起來,那問題就簡單了。
后來看到了一個(gè)式子,頓時(shí)有了點(diǎn)靈感 : (4)^3 = (-4)^4 + (4 - 1) * (-4)^3
想了想后總結(jié)出來了一個(gè)結(jié)論
①當(dāng)k是奇數(shù)的時(shí)候, 2^k = (-2)^(k+1) + (-2)^k;
②當(dāng)k是偶數(shù)的時(shí)候, 2^k = (-2)^k;
推導(dǎo)的過程中也有遇到一些問題,一直想把偶數(shù)和奇數(shù)的情況聯(lián)系在一起,但是感覺做不到,而且可能會(huì)出現(xiàn)負(fù)數(shù),出現(xiàn)負(fù)數(shù)就不好處理了。
有了以上的結(jié)論,差不多就可以開始動(dòng)手了。但是突然想到,負(fù)數(shù)的話,算出來的東西就會(huì)出問題了,想了想,負(fù)數(shù)和整數(shù)應(yīng)該有類似的結(jié)論,經(jīng)過嘗試后推倒出這樣的結(jié)論。
①當(dāng)k是奇數(shù)的時(shí)候, -2^k = (-2)^k;
②當(dāng)k是偶數(shù)的時(shí)候, -2^k = (-2)^(k + 1) + (-2)^(k + 1);
接下來就開始寫代碼了,但是測試了一下,一些數(shù)轉(zhuǎn)化后出現(xiàn)了讓人覺得很囧的大于1的數(shù)字,突然想到還要經(jīng)行進(jìn)位處理。想了想挺容易推導(dǎo)的,但是注意最好不要出現(xiàn)負(fù)數(shù)的情況,不然就不好處理了。
2 * (-2)^k = (-2)^(k + 1) + (-2)^(k + 2);
于是進(jìn)位的操作就ok了
但程序到這里還是有bug的,試了一下1000,000,000,結(jié)果發(fā)現(xiàn)后面的結(jié)果還是很正常,前面多出了個(gè)4,頓時(shí)覺得很納悶,然后認(rèn)真地調(diào)試了下,發(fā)現(xiàn)出現(xiàn)了一個(gè)4和2的循環(huán),高位的系數(shù)是2,低位的系數(shù)是4,突然反應(yīng)過來,完全是可以抵消掉的,但是沒有抵消就出現(xiàn)了4和2的循環(huán)。
ans[k+1] = 2ans[k];
每次進(jìn)位前先進(jìn)行抵消操作,然后開始進(jìn)位,接下來程序終于沒了bug了,順利AC了。
其實(shí)這個(gè)還是可以推廣的,按照剛才的公式,我們假設(shè)現(xiàn)在是(-b)進(jìn)制,有以下的結(jié)論
n為正數(shù)
①當(dāng)k為奇數(shù)的時(shí)候,b^k = (-b)^(k + 1) + (b - 1) * (-b)^k
②當(dāng)k為偶數(shù)的時(shí)候,b^k = (-b)^k;
n為負(fù)數(shù)
①當(dāng)k為奇數(shù)的時(shí)候,- b^k = (-b)^k;
②當(dāng)k為偶數(shù)的時(shí)候,- b^k = (-b)^(k + 1) + (b - 1) * (-b) ^ k;
進(jìn)位:
①當(dāng)k為偶數(shù)的時(shí)候,b * (-b)^k = (-b)^(k + 1);
②當(dāng)k為奇數(shù)的時(shí)候,b * (-b)^k = - b^(k + 1) = - (-b)^(k + 1) = - b^(k + 1) =?(-b)^(k + 2) + (b - 1) * (-b)^(k + 1);
抵消
ans[k+1] = b * ans[k];
?
#include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long LL; const int MAXN = 64 + 5;int n, flag; int ans[MAXN];int main() {int tCase;while(scanf("%d", &tCase) != EOF)for(int T = 1; T <= tCase; ++ T){flag = 1;scanf("%d", &n);memset(ans, 0, sizeof(ans));if(n < 0){flag = 0;n = ~n + 1;}//轉(zhuǎn)化for(int i = 0; i < 31; ++ i)if(n & (1 << i)){++ans[i];if((i & 1) == flag)++ans[i + 1];}//進(jìn)位for(int i = 0; i < MAXN - 1; ++ i){//抵消if(ans[i] >= ((ans[i + 1] >> 1) << 1)){ans[i] -= ((ans[i + 1] >> 1) << 1);ans[i + 1] -= (ans[i + 1] >> 1);}while(ans[i] > 1){++ans[i + 1];++ans[i + 2];ans[i] -= 2;}}printf("Case #%d: ", T);for(int i = MAXN - 1; i > 0; -- i)if(ans[i] != 0){for(int j = i; j > 0; --j)putchar(ans[j] + '0');break;}putchar(ans[0] + '0');putchar('\n');}return 0; } View Code?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/tank39/p/3911404.html
總結(jié)
以上是生活随笔為你收集整理的UVa 11121 - Base -2 负进制的转化和推广的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql-connector-java
- 下一篇: sharepoint 判断用户是否存在某