1 条题解
-
0
题目分析
本题要求将循环小数表示的字符串转换为最简分数,且分母最小。关键在于确定循环节的位置,计算对应的分数,并选择分母最小的解。
解题思路
循环节判断: 对于小数点后的数字序列,枚举所有可能的循环节起点i和终点j,判断从i到j是否为循环节(即后续数字是否重复该序列)。 分数计算: 纯循环小数(循环节从第一位开始): 设循环节长度为l,则分数为循环节数值 / 。 混循环小数(循环节前有非循环部分): 设非循环部分长度为a,循环节长度为b,则分数为(非循环部分数值 * 循环节数值) / ,如$0.12333...对应(12*(10-1)+3)/(10^2*(10-1)) = 111/900 = 37/300$。 最简分数选择: 枚举所有可能的循环节后,计算对应的分数并约分,选择分母最小的分数。若分母相同,选择分子较小的(确保最简)。 #include #include // 添加头文件以声明scanf和printf using namespace std; typedef unsigned long long ll;
int shuwei[2023]; int len; ll num; ll ansFenzi, ansFenmu; char str[2023]; ll tenPow[2023]; ll fenzi, fenmu, fenziXunhuan, fenmuXunhuan, fenziBuXunhuan, fenmuBuXunhuan;
void initTenPow() { tenPow[0] = 1; for (int i = 1; i <= 18; i++) { tenPow[i] = tenPow[i - 1] * 10; } }
bool input() { scanf("%s", str); // 使用scanf读取输入字符串 if (str[1] == '\0') { // 处理输入为"0"的情况 return false; } num = 0, len = 0; int i = 2; // 跳过"0."部分 while (str[i] != '\0' && str[i] != '.') { // 处理可能的"..."或直接数字 num = (str[i] - '0') + num * 10; shuwei[++len] = str[i] - '0'; i++; } return true; }
bool judgeXunhuanPossible(int i, int j) { int xunhuanLen = j - i + 1; for (; i + xunhuanLen <= len; i++) { if (shuwei[i] != shuwei[i + xunhuanLen]) { return false; } } return true; }
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
void calcBuxunhuan(int i, int j) { fenziBuXunhuan = 0, fenmuBuXunhuan = 0; if (i == 1) return; for (int k = 1; k < i; k++) { fenziBuXunhuan = fenziBuXunhuan * 10 + shuwei[k]; } fenmuBuXunhuan = tenPow[i - 1]; ll gcdNum = gcd(fenmuBuXunhuan, fenziBuXunhuan); fenziBuXunhuan /= gcdNum; fenmuBuXunhuan /= gcdNum; }
void calcXunhuan(int i, int j) { fenziXunhuan = 0; for (int k = i; k <= j; k++) { fenziXunhuan = fenziXunhuan * 10 + shuwei[k]; } fenmuXunhuan = tenPow[j - i + 1] - 1; ll gcdNum = gcd(fenmuXunhuan, fenziXunhuan); fenziXunhuan /= gcdNum; fenmuXunhuan /= gcdNum; if (i != 1) { fenmuXunhuan *= tenPow[i - 1]; gcdNum = gcd(fenmuXunhuan, fenziXunhuan); fenziXunhuan /= gcdNum; fenmuXunhuan /= gcdNum; } }
void calcWholeFenshu() { if (fenziBuXunhuan != 0) { ll lcmNum = lcm(fenmuBuXunhuan, fenmuXunhuan); fenziXunhuan *= lcmNum / fenmuXunhuan; fenziBuXunhuan *= lcmNum / fenmuBuXunhuan; fenzi = fenziXunhuan + fenziBuXunhuan; fenmu = lcmNum; ll gcdNum = gcd(fenmu, fenzi); fenmu /= gcdNum; fenzi /= gcdNum; } else { fenzi = fenziXunhuan; fenmu = fenmuXunhuan; } if (ansFenmu > fenmu || (ansFenmu == fenmu && fenzi < ansFenzi)) { ansFenmu = fenmu; ansFenzi = fenzi; } }
void initAnsFenziFenmu() { ansFenzi = num; ansFenmu = tenPow[len] - 1; ll gcdNum = gcd(ansFenmu, ansFenzi); ansFenzi /= gcdNum; ansFenmu /= gcdNum; }
int main() { initTenPow(); while (input()) { initAnsFenziFenmu(); for (int i = 1; i <= len; i++) { for (int j = i; j <= len; j++) { if (judgeXunhuanPossible(i, j)) { calcBuxunhuan(i, j); calcXunhuan(i, j); calcWholeFenshu(); } } } printf("%lld/%lld\n", ansFenzi, ansFenmu); // 使用printf输出结果 } return 0; }
- 1
信息
- ID
- 931
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者