UVa 11121 - Base -2 负进制的转化和推广
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2062
題目大意就是給你一個-1000,000,000到1000,000,000的數轉化成-2進制。
看到-2就想到了2進制,原先想兩位兩位地考慮,然后看成2進制的,接下來求一下方程的正數解就行了,然后將那些數全都轉化成0和1,后來又發現。。每項之間差了4倍,頓時就不行了。接著想著是不是能將 (-2)^k 和 2^k 聯系起來,那問題就簡單了。
后來看到了一個式子,頓時有了點靈感 : (4)^3 = (-4)^4 + (4 - 1) * (-4)^3
想了想后總結出來了一個結論
①當k是奇數的時候, 2^k = (-2)^(k+1) + (-2)^k;
②當k是偶數的時候, 2^k = (-2)^k;
推導的過程中也有遇到一些問題,一直想把偶數和奇數的情況聯系在一起,但是感覺做不到,而且可能會出現負數,出現負數就不好處理了。
有了以上的結論,差不多就可以開始動手了。但是突然想到,負數的話,算出來的東西就會出問題了,想了想,負數和整數應該有類似的結論,經過嘗試后推倒出這樣的結論。
①當k是奇數的時候, -2^k = (-2)^k;
②當k是偶數的時候, -2^k = (-2)^(k + 1) + (-2)^(k + 1);
接下來就開始寫代碼了,但是測試了一下,一些數轉化后出現了讓人覺得很囧的大于1的數字,突然想到還要經行進位處理。想了想挺容易推導的,但是注意最好不要出現負數的情況,不然就不好處理了。
2 * (-2)^k = (-2)^(k + 1) + (-2)^(k + 2);
于是進位的操作就ok了
但程序到這里還是有bug的,試了一下1000,000,000,結果發現后面的結果還是很正常,前面多出了個4,頓時覺得很納悶,然后認真地調試了下,發現出現了一個4和2的循環,高位的系數是2,低位的系數是4,突然反應過來,完全是可以抵消掉的,但是沒有抵消就出現了4和2的循環。
ans[k+1] = 2ans[k];
每次進位前先進行抵消操作,然后開始進位,接下來程序終于沒了bug了,順利AC了。
其實這個還是可以推廣的,按照剛才的公式,我們假設現在是(-b)進制,有以下的結論
n為正數
①當k為奇數的時候,b^k = (-b)^(k + 1) + (b - 1) * (-b)^k
②當k為偶數的時候,b^k = (-b)^k;
n為負數
①當k為奇數的時候,- b^k = (-b)^k;
②當k為偶數的時候,- b^k = (-b)^(k + 1) + (b - 1) * (-b) ^ k;
進位:
①當k為偶數的時候,b * (-b)^k = (-b)^(k + 1);
②當k為奇數的時候,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;}//轉化for(int i = 0; i < 31; ++ i)if(n & (1 << i)){++ans[i];if((i & 1) == flag)++ans[i + 1];}//進位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?
?
?
?
轉載于:https://www.cnblogs.com/tank39/p/3911404.html
總結
以上是生活随笔為你收集整理的UVa 11121 - Base -2 负进制的转化和推广的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql-connector-java
- 下一篇: CentOS 安装Python 3.52