1. 程式人生 > >洛谷P017 進位制轉換 NOIP2000年提高組第一題真題

洛谷P017 進位制轉換 NOIP2000年提高組第一題真題

洛谷P017 進位制轉換 2000年NOIP真題

解題思路:

將正整數n寫成r進位制的形式,當r為正整數的時候,想必大家都知道怎麼寫,那就是不停地將n對r取模,再將n/=r就可以得到r進位制的n了。

vector<int>v;
while(n){
	v.push_back(n%r);
	n /= r;
}

然而當r為負整數的時候,n/r和n%r的結果將不再是我們期待的那樣,此時n%r的結果將總是非正數。例如:(8)÷(3)=2(2)(-8)\div(-3)=2\cdots(-2),而我們這道題要求的是r進位制每一位的係數都是非負數,即希望出現 (8)

÷(3)=31(-8)\div(-3)=3\cdots1 的結果,其實想要這樣其實很簡單,只需要重寫一下C++中的除法運算和模運算的運算規則就好了,就是當除數為負數的時候,商加1,餘數減r。如下所示:

我是將n和r分別為正負的時候都寫了出來,以防以後遇到這種題也是一勞永逸。本題只需要關心r為負數的情況就好了。

pair<int, int> div_mod(int n, int r) {
    if (n >= 0) {
        return make_pair(n / r, n % r);
    }
    if (n % r == 0
) { return make_pair(n / r, 0); } if (r < 0) { return make_pair(n / r + 1, n % r - r); } return make_pair(-n / r + 1, n % r - r); }

完整AC程式碼:

#include <bits/stdc++.h>
using namespace std;
string D = "0123456789ABCDEFGHIJ";

pair<int, int> div_mod(int n, int r)
{ if (n >= 0) { return make_pair(n / r, n % r); } if (n % r == 0) { return make_pair(n / r, 0); } if (r < 0) { return make_pair(n / r + 1, n % r - r); } return make_pair(-n / r + 1, n % r - r); } int main(int argc, char const *argv[]) { int n, base; cin >> n >> base; int n1 = n; vector<int> v; int r = base; while (n) { pair<int, int> res = div_mod(n, r); v.push_back(res.second); n = res.first; } reverse(v.begin(), v.end()); cout << n1 << "="; for (auto item:v) { cout << D[item]; } cout << "(base" << base << ")" << endl; return 0; }