結果
| 問題 |
No.1842 Decimal Point
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-10-15 18:33:26 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,491 bytes |
| コンパイル時間 | 891 ms |
| コンパイル使用メモリ | 83,352 KB |
| 実行使用メモリ | 180,572 KB |
| 最終ジャッジ日時 | 2025-10-15 18:33:37 |
| 合計ジャッジ時間 | 10,481 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | WA * 1 TLE * 2 -- * 2 |
ソースコード
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
long long A, B, C;
cin >> A >> B >> C;
// 处理整除情况:小数部分全为0
if (A % B == 0) {
cout << "0\n";
continue;
}
// 提取余数(小数部分由余数决定)
long long rem = A % B;
// 消除B中所有2和5的因子,计算非循环前缀长度
int a = 0, b = 0;
long long temp_B = B;
while (temp_B % 2 == 0) {
temp_B /= 2;
a++;
}
while (temp_B % 5 == 0) {
temp_B /= 5;
b++;
}
int prefix_len = max(a, b);
// 情况1:C在非循环前缀范围内
if (C <= prefix_len) {
long long current_rem = rem;
for (int i = 0; i < C; ++i) {
current_rem *= 10;
if (i == C - 1) {
cout << current_rem / B << '\n';
break;
}
current_rem %= B;
// 若余数变为0,后续全为0
if (current_rem == 0) {
cout << "0\n";
break;
}
}
continue;
}
// 情况2:C在循环部分(需处理大C值)
// 1. 先将余数推进到循环部分起点
long long current_rem = rem;
for (int i = 0; i < prefix_len; ++i) {
current_rem = (current_rem * 10) % B;
}
// 2. 寻找循环节
unordered_map<long long, int> rem_pos; // 记录余数首次出现的位置
int pos = 0; // 当前是循环部分的第几位(从0开始)
long long target_rem = current_rem;
int cycle_start = -1, cycle_len = -1;
while (true) {
if (rem_pos.count(target_rem)) {
cycle_start = rem_pos[target_rem];
cycle_len = pos - cycle_start;
break;
}
rem_pos[target_rem] = pos;
target_rem = (target_rem * 10) % temp_B; // 用消去因子后的B计算更高效
pos++;
}
// 3. 计算C在循环部分的位置
long long cycle_pos = C - prefix_len - 1; // 循环部分从0开始计数
if (cycle_pos < cycle_start) {
// 还没进入循环节,直接计算
target_rem = current_rem;
for (int i = 0; i <= cycle_pos; ++i) {
if (i == cycle_pos) {
cout << (target_rem * 10) / temp_B << '\n';
break;
}
target_rem = (target_rem * 10) % temp_B;
}
} else {
// 已进入循环节,计算循环偏移
long long offset = (cycle_pos - cycle_start) % cycle_len;
long long final_pos = cycle_start + offset;
// 找到循环节中对应位置的数字
target_rem = current_rem;
for (int i = 0; i <= final_pos; ++i) {
if (i == final_pos) {
cout << (target_rem * 10) / temp_B << '\n';
break;
}
target_rem = (target_rem * 10) % temp_B;
}
}
}
return 0;
}