摘要:本文是PTA编程题"有理数均值"的题解,涵盖题目描述、输入输出格式及C++语言实现,展示核心算法:最大公约数(GCD)约分、分数通分累加求平均。
题目描述
本题要求编写程序,计算N个有理数的平均值。
输入格式:
输入第一行给出正整数N(≤100);第二行中给出N个分数形式的有理数,其中分子和分母全是整形范围内的整数(正负均可),没有分母为0的情况。
输出格式:
在一行中按照a/b的格式输出N个有理数的平均值。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。
输入样例:
in
4
1/2 1/6 3/6 -5/10
输出样例:
out
-1/12
解题思路
核心问题分析
本题需要解决的核心问题:
- 分数输入解析:识别输入中的分数格式(分子/分母)或整数格式
- 分数累加求和:多个分数相加需要通分,避免浮点数精度丢失
- 求平均值:总和除以个数N
- 最简分数输出:用最大公约数约分,保证分母为正
算法原理说明
- 辗转相除法(GCD) :用于求最大公约数,对分数进行约分。公式:
gcd(a, b) = gcd(b, a % b),直到b为0时a即为最大公约数 - 分数加法 :
a/b + c/d = (a*d + c*b) / (b*d),每次累加后立即约分防止溢出 - 求平均值:将累加后的分母乘以N,再进行约分
- 符号处理:确保负号在分子上,分母始终为正
具体计算步骤
- 输入N,初始化分子sumNum=0,分母sumDen=1
- 对每个分数:
- 解析分子num和分母den
- 通分累加:
sumNum = sumNum*den + num*sumDen,sumDen = sumDen*den - 用GCD约分化简
- 求平均:
sumDen *= N,再次约分 - 若分母为负,分子分母同时取反
- 按格式输出结果
代码流程说明
1. gcd函数(第32-36行)
- 输入:两个长整数a、b
- 功能:求最大公约数
- 流程:先取绝对值,再用辗转相除法递归求解
2. main函数-初始化(第38-42行)
- 输入N
- 初始化累计分子sumNum=0,累计分母sumDen=1
3. main函数-分数解析与累加(第44-64行)
- 循环N次读取每个分数字符串
- 查找'/'位置:有则拆分分子分母,无则分母为1
- 通分公式累加分子分母
- 每次累加后用GCD约分,避免数值过大
4. main函数-求平均与最终约分(第66-74行)
- sumDen乘以N求平均值
- 再次GCD约分
- 若分母为负,分子分母同时取反保证分母为正
5. main函数-输出(第76-80行)
- 分母为1时只输出分子
- 否则输出"分子/分母"格式
代码流程图
#mermaid-svg-oEdD3IBSxTFZsblF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oEdD3IBSxTFZsblF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oEdD3IBSxTFZsblF .error-icon{fill:#552222;}#mermaid-svg-oEdD3IBSxTFZsblF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oEdD3IBSxTFZsblF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oEdD3IBSxTFZsblF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oEdD3IBSxTFZsblF .marker.cross{stroke:#333333;}#mermaid-svg-oEdD3IBSxTFZsblF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oEdD3IBSxTFZsblF p{margin:0;}#mermaid-svg-oEdD3IBSxTFZsblF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oEdD3IBSxTFZsblF .cluster-label text{fill:#333;}#mermaid-svg-oEdD3IBSxTFZsblF .cluster-label span{color:#333;}#mermaid-svg-oEdD3IBSxTFZsblF .cluster-label span p{background-color:transparent;}#mermaid-svg-oEdD3IBSxTFZsblF .label text,#mermaid-svg-oEdD3IBSxTFZsblF span{fill:#333;color:#333;}#mermaid-svg-oEdD3IBSxTFZsblF .node rect,#mermaid-svg-oEdD3IBSxTFZsblF .node circle,#mermaid-svg-oEdD3IBSxTFZsblF .node ellipse,#mermaid-svg-oEdD3IBSxTFZsblF .node polygon,#mermaid-svg-oEdD3IBSxTFZsblF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oEdD3IBSxTFZsblF .rough-node .label text,#mermaid-svg-oEdD3IBSxTFZsblF .node .label text,#mermaid-svg-oEdD3IBSxTFZsblF .image-shape .label,#mermaid-svg-oEdD3IBSxTFZsblF .icon-shape .label{text-anchor:middle;}#mermaid-svg-oEdD3IBSxTFZsblF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oEdD3IBSxTFZsblF .rough-node .label,#mermaid-svg-oEdD3IBSxTFZsblF .node .label,#mermaid-svg-oEdD3IBSxTFZsblF .image-shape .label,#mermaid-svg-oEdD3IBSxTFZsblF .icon-shape .label{text-align:center;}#mermaid-svg-oEdD3IBSxTFZsblF .node.clickable{cursor:pointer;}#mermaid-svg-oEdD3IBSxTFZsblF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oEdD3IBSxTFZsblF .arrowheadPath{fill:#333333;}#mermaid-svg-oEdD3IBSxTFZsblF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oEdD3IBSxTFZsblF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oEdD3IBSxTFZsblF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oEdD3IBSxTFZsblF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oEdD3IBSxTFZsblF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oEdD3IBSxTFZsblF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oEdD3IBSxTFZsblF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oEdD3IBSxTFZsblF .cluster text{fill:#333;}#mermaid-svg-oEdD3IBSxTFZsblF .cluster span{color:#333;}#mermaid-svg-oEdD3IBSxTFZsblF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oEdD3IBSxTFZsblF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oEdD3IBSxTFZsblF rect.text{fill:none;stroke-width:0;}#mermaid-svg-oEdD3IBSxTFZsblF .icon-shape,#mermaid-svg-oEdD3IBSxTFZsblF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oEdD3IBSxTFZsblF .icon-shape p,#mermaid-svg-oEdD3IBSxTFZsblF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oEdD3IBSxTFZsblF .icon-shape .label rect,#mermaid-svg-oEdD3IBSxTFZsblF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oEdD3IBSxTFZsblF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oEdD3IBSxTFZsblF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oEdD3IBSxTFZsblF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
是
否
否
是
否
是
否
开始
输入分数个数N
初始化累加分子分母
i小于N?
读取分数字符串
包含斜杠分隔符?
拆分分子分母
整数值为分子分母为1
通分累加分子分母
GCD约分化简
i加1
分母乘N求平均值
最终GCD约分
分母为负数?
分子分母同时取反
分母等于1?
只输出分子
输出分子斜杠分母
结束
解题流程图
#mermaid-svg-2Ruqw9KtJv9mLzI2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .error-icon{fill:#552222;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .marker.cross{stroke:#333333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 p{margin:0;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .cluster-label text{fill:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .cluster-label span{color:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .cluster-label span p{background-color:transparent;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .label text,#mermaid-svg-2Ruqw9KtJv9mLzI2 span{fill:#333;color:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .node rect,#mermaid-svg-2Ruqw9KtJv9mLzI2 .node circle,#mermaid-svg-2Ruqw9KtJv9mLzI2 .node ellipse,#mermaid-svg-2Ruqw9KtJv9mLzI2 .node polygon,#mermaid-svg-2Ruqw9KtJv9mLzI2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .rough-node .label text,#mermaid-svg-2Ruqw9KtJv9mLzI2 .node .label text,#mermaid-svg-2Ruqw9KtJv9mLzI2 .image-shape .label,#mermaid-svg-2Ruqw9KtJv9mLzI2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .rough-node .label,#mermaid-svg-2Ruqw9KtJv9mLzI2 .node .label,#mermaid-svg-2Ruqw9KtJv9mLzI2 .image-shape .label,#mermaid-svg-2Ruqw9KtJv9mLzI2 .icon-shape .label{text-align:center;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .node.clickable{cursor:pointer;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .arrowheadPath{fill:#333333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2Ruqw9KtJv9mLzI2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2Ruqw9KtJv9mLzI2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2Ruqw9KtJv9mLzI2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .cluster text{fill:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .cluster span{color:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2Ruqw9KtJv9mLzI2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .icon-shape,#mermaid-svg-2Ruqw9KtJv9mLzI2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .icon-shape p,#mermaid-svg-2Ruqw9KtJv9mLzI2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .icon-shape .label rect,#mermaid-svg-2Ruqw9KtJv9mLzI2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2Ruqw9KtJv9mLzI2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2Ruqw9KtJv9mLzI2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2Ruqw9KtJv9mLzI2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
理解题目需求
选择分数运算方案
设计GCD约分函数
设计分数输入解析逻辑
设计累加算法通分加每次约分
设计求平均步骤分母乘N再约分
处理符号保证分母为正
设计格式化输出
编写完整代码
用样例验证
输出正确?
完成
检查GCD实现通分公式符号
代码部分实现
cpp
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
long long gcd(long long a, long long b) {
a = llabs(a);
b = llabs(b);
return b == 0 ? a : gcd(b, a % b);
}
int main() {
int n;
cin >> n;
long long sumNum = 0, sumDen = 1;
for (int i = 0; i < n; i++) {
string frac;
cin >> frac;
long long num, den;
size_t pos = frac.find('/');
if (pos != string::npos) {
num = stoll(frac.substr(0, pos));
den = stoll(frac.substr(pos + 1));
} else {
num = stoll(frac);
den = 1;
}
sumNum = sumNum * den + num * sumDen;
sumDen = sumDen * den;
long long g = gcd(sumNum, sumDen);
sumNum /= g;
sumDen /= g;
}
sumDen *= n;
long long g = gcd(sumNum, sumDen);
sumNum /= g;
sumDen /= g;
if (sumDen < 0) {
sumNum = -sumNum;
sumDen = -sumDen;
}
if (sumDen == 1) {
cout << sumNum << endl;
} else {
cout << sumNum << "/" << sumDen << endl;
}
return 0;
}