记录65
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b) {
a=abs(a);
b=abs(b);
while(b){
int t=b;
b=a%b;
a=t;
}
return a;
}
int main(){
int a1=0,a2=1,b1,b2,cnt=0;
string s,st;
cin>>s;
bool f=0;
for(int i=0;i<s.size();i++){
int num=i;
while(s[i]!='/') i++;
st=s.substr(num,i-num);
b1=stoi(st);
num=++i;
while(s[i]>='0'&&s[i]<='9') i++;
st=s.substr(num,i-num);
b2=stoi(st);
i--;
a1=a1*b2+b1*a2;
a2=a2*b2;
int t=gcd(a1,a2);
a1/=t;
a2/=t;
}
if(a2==1) cout<<a1;
else cout<<a1<<'/'<<a2;
return 0;
}
题目传送门
https://www.luogu.com.cn/problem/P1572
突破口
分数计算题,最后的计算结果(用为整数则用整数表示,否则用最简分数表示)
保证,直接从前往后直接计算分数的和或者差,然后立刻化简,这么做的中间结果不会超过 int 的范围。
思路
- 要进行约分 👉 gcd函数
- 模拟分数的通分运算
- 每次运算后将结果化简
代码简析
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b) {
a=abs(a);
b=abs(b);
while(b){
int t=b;
b=a%b;
a=t;
}
return a;
}
int main(){
int a1=0,a2=1,b1,b2,cnt=0;
string s,st;
cin>>s;
bool f=0;
for(int i=0;i<s.size();i++){
int num=i;
while(s[i]!='/') i++;
st=s.substr(num,i-num);
b1=stoi(st);
num=++i;
...
}
...
return 0;
}
int gcd(int a, int b) {} 👉 计算最大公约数
首先明确:最大公约数(GCD)的数学定义是「两个整数的最大正整数公约数」,因此结果必须是非负的,所以用abs函数转换两个为正数
int a1=0(分子a),a2=1(分母a),b1(分子b),b2(分母b),cnt=0(没用变量,忘删了);
输入一个分数然后加上前一个分数,所以初始化前一个分数的分母必须为1,分子为0
string s(分数式子),st(切出来的数字);
bool f=0(没用2号,也忘删了);
int num=i; 👉 记录数字开始下标,此处为分子
while(s[i]!='/') i++; 👉 没遇到/,代表还在找数字
st=s.substr(num,i-num); 👉 切出来数字了
注意:此时i指向的是/的位置,所以i-num就是数字的长度
b1=stoi(st); 👉 字符串转数字,得到分子
注意:关于stoi函数,放在补充部分来介绍
num=++i; 👉 存分母开始的下标
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b) {
a=abs(a);
b=abs(b);
while(b){
int t=b;
b=a%b;
a=t;
}
return a;
}
int main(){
int a1=0,a2=1,b1,b2;
string s,st;
cin>>s;
for(int i=0;i<s.size();i++){
int num=i;
while(s[i]!='/') i++;
st=s.substr(num,i-num);
b1=stoi(st);
num=++i;
while(s[i]>='0'&&s[i]<='9') i++;
st=s.substr(num,i-num);
b2=stoi(st);
i--;
a1=a1*b2+b1*a2;
a2=a2*b2;
int t=gcd(a1,a2);
a1/=t;
a2/=t;
}
if(a2==1) cout<<a1;
else cout<<a1<<'/'<<a2;
return 0;
}
while(s[i]>='0'&&s[i]<='9') i++; 👉 得到数字后的位置
st=s.substr(num,i-num); 👉 切片得到分母的数字
b2=stoi(st); 👉 分母转换为整数类型
i--; 👉 回到分母数字的尾巴的下标,因为进入下一次for循环会自动移动i,然后遇到下一个分子
a1=a1*b2+b1*a2; 👉 分子进行计算
a2=a2*b2; 👉 分母进行运算
int t=gcd(a1,a2);a1/=t;a2/=t; 👉 约分存入a分数,后面得到b分数加它
if(a2==1) cout<<a1; 👉 分母是1,直接输出整数
else cout<<a1<<'/'<<a2; 👉 输出最简分数结果
补充
在 CSP 比赛中 stoi 函数的可用性,以及 stoll 函数的相关使用规则
一、stoi 函数在 CSP 比赛中的应用与负数转换
1. CSP 比赛中是否可用
可以使用。CSP(计算机软件能力认证)的编译环境通常采用 GCC 编译器,且默认支持 C++11 及以上标准,而
stoi是 C++11 引入的标准库函数(定义在<string>头文件中),因此在 CSP 比赛中使用stoi是完全合规且被支持的。2. 能否转换负数
可以转换负数。
stoi能够正确解析以负号-开头的数字字符串(如"-123"),也支持解析以正号+开头的字符串(如"+456"),最终转换为对应的 int 类型整数。补充:stoi 的注意事项
- 数值范围:
stoi的转换结果受 int 类型范围限制(通常为 −231 ~ 231−1,即 - 2147483648 ~ 2147483647),超出范围会抛出out_of_range异常;- 输入要求:字符串需为合法数字格式(仅允许开头的正负号 + 数字),若包含非数字字符(如
"12a3"),会抛出invalid_argument异常;- 头文件:使用时必须包含
<string>头文件。二、stoll 函数的相关说明
1. CSP 比赛中是否可用
可以使用。
stoll同样是 C++11 标准库函数(定义在<string>头文件中),与stoi一样被 CSP 比赛的编译环境支持。2. 核心特性
- 功能:将字符串转换为
long long类型的整数;- 负数支持:支持转换负数,规则与 stoi 一致(可解析
"-1234567890123"这类负数字符串);- 数值范围:
long long的范围为 −263 ~ 263−1(即 - 9223372036854775808 ~ 9223372036854775807),远大于 int,适合处理 CSP 中常见的大数场景;- 其他规则:输入格式要求、异常类型与 stoi 完全一致。
三、示例代码
#include <iostream> #include <string> using namespace std; int main() { // stoi转换负数、正数 string s1 = "-12345"; string s2 = "+67890"; int num1 = stoi(s1); int num2 = stoi(s2); cout << "stoi转换结果:" << num1 << " " << num2 << endl; // 输出:-12345 67890 // stoll转换大数负数 string s3 = "-1234567890123456789"; long long num3 = stoll(s3); cout << "stoll转换结果:" << num3 << endl; // 输出:-1234567890123456789 return 0; }总结
stoi和stoll均可在 CSP 比赛中使用(C++11 标准支持),且都能正确转换负数;stoi适用于 int 范围的整数转换,stoll适用于 long long 范围的大数转换;- 使用时需包含
<string>头文件,确保输入字符串为合法数字格式,避免超出类型范围。

851

被折叠的 条评论
为什么被折叠?



