2017年第八屆真題 小數第n位

題目描述

我們知道,整數做除法時,有時得到有限小數,有時得到無限循環小數。

如果我們把有限小數的末尾加上無限多個0,它們就有了統一的形式。

本題的任務是:在上面的約定下,求整數除法小數點後的第n位開始的3位數。

輸入

一行三個整數:a b n,用空格分開。a是被除數,b是除數,n是所求的小數後位置(0<a,b,n<1000000000)

輸出

一行3位數字,表示:a除以b,小數後第n位開始的3位數字。

樣例輸入

1 8 1

樣例輸出

125

樣例輸入

1 8 3

樣例輸出

500

解題思路

這個數據範圍,只能模擬除法了

舉個具體的例子:當我們要求 1 / 7 的第二位小數4時,

具體過程相當於是 1 % 7 * 10 % 7 * 10 / 7,

取模與乘法運算滿足交換律 且 a % m * b % m = a * b % m

因此上面這個式子以又可以寫成 1 * 10^(2-1) % 7 * 10 / 7

由於這個n也是巨大的,常規求冪的方式行不通,所以肯定要用到快速冪

AC代碼

#include<iostream>

using namespace std;

long long gcd(long long m, long long n) {
  return m % n == 0 ? n : gcd(n, m % n);
}

long long quick_pow(long long n, long long k, long long mod) {
  long long res = 1, base = n % mod;
  while (k) {
    if (k & 1) res = (res % mod) * (base % mod) % mod;
    base = ((base % mod) * (base % mod)) % mod;
    k >>= 1;
  }
  return res;
}

int main() {
  long long m, n, k1, k2;
  cin >> m >> n >> k1;
  k2 = k1 + 2;
  long long gcd_mn = gcd(m, n);
  m /= gcd_mn, n /= gcd_mn; // 先約分
  long long res = (m * quick_pow(10, k1 - 1, n)) % n;
  for (long long i = k1; i <= k2; i++) {
    res *= 10;
    cout << res / n;
    res %= n;
  }
  return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章