日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

信息学奥赛一本通 1820:【00NOIP提高组】进制转换 | 洛谷 P1017 [NOIP2000 提高组] 进制转换

發布時間:2025/3/17 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息学奥赛一本通 1820:【00NOIP提高组】进制转换 | 洛谷 P1017 [NOIP2000 提高组] 进制转换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目鏈接】

ybt 1820:【00NOIP提高組】進制轉換
洛谷 P1017 [NOIP2000 提高組] 進制轉換
注意:兩OJ上題目內容相同,輸入輸出要求不同

【題目考點】

1.數制

【解題思路】

在題目描述下,對負數r進制數字n,各位為dndn?1...d1d0d_nd_{n-1}...d_1d_0dn?dn?1?...d1?d0?,按位權展開為:
n=dn?rn+dn?1?rn?1+...+d1?r1+d0?r0n = d_n*r^n+d_{n-1}*r^{n-1}+...+d_1*r^1+d_0*r^0n=dn??rn+dn?1??rn?1+...+d1??r1+d0??r0
其中d0,d1,...,dnd_0,d_1,...,d_nd0?,d1?,...,dn?必須都為正數
除去最后一項,其余項加和一定是r的倍數:
dn?rn+dn?1?rn?1+...+d1?r1=r?(dn?rn?1+dn?1?rn?2+...+d1?r0)d_n*r^n+d_{n-1}*r^{n-1}+...+d_1*r^1 = r\cdot (d_n*r^{n-1}+d_{n-1}*r^{n-2}+...+d_1*r^0)dn??rn+dn?1??rn?1+...+d1??r1=r?(dn??rn?1+dn?1??rn?2+...+d1??r0),簡記為r?qr\cdot qr?q
n=r?q+d0?n?d0=r?qn = r\cdot q + d_0 \Rightarrow n-d_0 = r\cdot qn=r?q+d0??n?d0?=r?q
其中0≤d0<∣r∣0\le d_0<|r|0d0?<r
n需要減一個非負數d0d_0d0?,使其是r的整數倍。
d0d_0d0?即為r在可能為負數情況下廣義的“n對r取?!钡闹?。該值無法在c++中通過n%r得到。

方法1:

枚舉從0到|r|-1的所有值,看哪一個滿足n減去它后是r的整數倍。

int mod(int a, int b)//求a對b取模的值,在a,b為負數條件下依然適用 {for(int r = 0; r < abs(b); ++r){if((a-r)%b == 0)return r;} }

方法2:

先求n/r=xn / r = xn/r=x,那么有:n=r?x+mn = r*x + mn=r?x+m,此時一定有∣m∣<∣r∣|m|<|r|m<r
m的值可能是正的也可能是負的。
根據上文結論:n需要減一個非負數,使其是r的整數倍。,所以必須讓m≥0m\ge0m0
如果m<0m<0m<0,則公式化為:n=r?(x+1)+m?rn = r*(x+1)+m-rn=r?(x+1)+m?r。
m?rm-rm?r一定是非負數。
根據該原理,mod函數可以設計為:可以直接求商,再求余數,如果余數是負數,那么再減一個除數,使其變為非負數。

int mod(int a, int b) {int x = a / b, m;//x:商 m:余數m = a - x*b;if(m < 0)m = m - b;return m; }

以上兩種mod函數求兩個整數取模的值,在運算數是正數、負數條件下都適用。
用mod函數求d0d_0d0?的值,記錄在數組中。
而后計算n=(n?d0)/rn=(n-d_0)/rn=(n?d0?)/r,再用同樣的方法求出下一個數位d1d_1d1?。
如此循環,直到n為0。
最后輸出記錄的各位數字。輸出時,注意將10以上的數字轉為字母。

【題解代碼】

ybt 1820:【00NOIP提高組】進制轉換

注意處理多組數據,要做狀態還原

#include<bits/stdc++.h> using namespace std; int num[50], ni; int mod(int a, int b) {for(int r = 0; r < abs(b); ++r){if((a-r)%b == 0)return r;} } int main() {int n, r, a, m;while(cin >> n >> r)//r:基數 {ni = 0;//狀態還原 a = n;do//用do...while,即便a為0,也會填充到數組中 {m = mod(a, r);//"取模"結果 num[++ni] = m;//將余數填充到數組中 a = (a - m) / r; }while(a != 0);for(int i = ni; i >= 1; --i)//高位到低位輸出數字 cout << (num[i] < 10 ? char(num[i]+'0') : char(num[i]-10+'A'));//若超過10,轉為16進制輸出 cout << endl;}return 0; }

洛谷 P1017 [NOIP2000 提高組] 進制轉換

#include<bits/stdc++.h> using namespace std; int num[50], ni; int mod(int a, int b) {for(int r = 0; r < abs(b); ++r){if((a-r)%b == 0)return r;} } int main() {int n, r, a, m;cin >> n >> r;//r:基數 a = n;do//用do...while,即便a為0,也會填充到數組中 {m = mod(a, r);num[++ni] = m;//將余數填充到數組中 a = (a - m) / r; }while(a != 0);cout << n << '=';for(int i = ni; i >= 1; --i)//高位到低位輸出數字 cout << (num[i] < 10 ? char(num[i]+'0') : char(num[i]-10+'A'));//若超過10,轉為16進制輸出 cout << "(base" << r << ")";return 0; }

使用第二種mod函數寫法:

#include<bits/stdc++.h> using namespace std; int num[50], ni; int mod(int a, int b) {int x = a / b, m;m = a - x*b;if(m < 0)m = m - b;return m; } int main() {int n, r, a, m;cin >> n >> r;//r:基數 cout << n << '=';a = n;do//用do...while,即便a為0,也會填充到數組中 {m = mod(a, r);num[++ni] = m;//將余數填充到數組中 a = (a - m) / r; }while(a != 0);for(int i = ni; i >= 1; --i)//高位到低位輸出數字 cout << (num[i] < 10 ? char(num[i]+'0') : char(num[i]-10+'A'));//若超過10,轉為16進制輸出 cout << "(base" << r << ")";return 0; }

總結

以上是生活随笔為你收集整理的信息学奥赛一本通 1820:【00NOIP提高组】进制转换 | 洛谷 P1017 [NOIP2000 提高组] 进制转换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。