杭电oj(2031、2033、2070、2071、2075、2089、2090、2092、2096)题解
目录
编辑
2031
题目
思路
1. 处理负数情况
2. 进行进制转换
3. 输出转换结果
代码
2033
题目
思路
代码
2070
题目
思路
1. 宏定义与数组定义
2. 计算斐波那契数列的前 51 项
代码
2071
题目
思路
循环处理每组数据
对每组数据进行降序排序
代码
2075
题目
思路
代码
2089
题目
思路
1.预处理所有可能的整数
2.循环读取区间并统计满足条件的整数个数
代码
2090
题目
思路
代码
2092
题目
思路
利用一元二次方程求解
根据判别式进行判断
判别式小于 0
判别式大于等于 0
代码
2096
题目
思路
代码
2031
题目
思路
将十进制数转换为指定进制的数,并将结果存储在
vector
中,最后逆序输出。对于负数,先输出负号再进行转换。对于大于 9 的数字,使用字母A
-F
表示,以支持十六进制等更高进制的转换。1. 处理负数情况
如果输入的十进制数
num
是负数,先输出负号-
,然后取其绝对值,将后续的转换操作都基于正数进行。2. 进行进制转换
- 初始化一个
vector<int>
类型的ans
容器,用于存储转换后的每一位数字。- 使用
while
循环,不断对num
进行取模和整除操作:
int a = num % jz;
:计算num
除以目标进制jz
的余数,这个余数就是转换后该位上的数字。ans.push_back(a);
:将余数添加到ans
容器中。num /= jz;
:将num
更新为整除jz
后的结果,继续下一轮计算。- 当
num
变为 0 时,说明转换完成。3. 输出转换结果
- 由于
ans
容器中存储的数字是从低位到高位的顺序,所以需要逆序输出。- 对于每一位数字,如果小于 10,直接输出该数字;如果大于等于 10,则根据其值输出对应的字母(
A
-F
),这是为了处理大于十进制的进制(如十六进制)。
代码
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
void change(int num,int jz){vector<int>ans;if(num<0) {cout<<'-';num=abs(num);}while(num>0){int a=num%jz;ans.push_back(a);num/=jz;}for(int i=ans.size()-1;i>=0;i--){if(ans[i]<10) cout<<ans[i];else if(ans[i]==10) cout<<'A';else if(ans[i]==11) cout<<'B';else if(ans[i]==12) cout<<'C';else if(ans[i]==13) cout<<'D';else if(ans[i]==14) cout<<'E';else if(ans[i]==15) cout<<'F';}ans.clear();return;
} int main(){int a,b;while(cin>>a>>b){change(a,b);cout<<endl;}return 0;
}
2033
题目
思路
通过循环读取多组时间,将每组时间的小时、分钟、秒分别相加,处理进位情况后输出相加结果。
- 秒数进位:如果相加后的秒数
cs
大于等于 60,说明需要向分钟进位,将分钟数cm
加 1,同时将秒数cs
对 60 取余,得到进位后的秒数。- 分钟数进位:如果相加后的分钟数
cm
大于等于 60,说明需要向小时进位,将小时数ch
加 1,同时将分钟数cm
对 60 取余,得到进位后的分钟数。
代码
#include<iostream>
using namespace std;
int n;
int ah,am,as,bh,bm,bs;
int ch,cm,cs;
int main(){cin>>n;for(int i=0;i<n;i++){cin>>ah>>am>>as>>bh>>bm>>bs;ch=ah+bh;cm=am+bm;cs=as+bs;if(cs>=60){cm++;cs%=60;}if(cm>=60){ch++;cm%=60;}cout<<ch<<" "<<cm<<" "<<cs<<endl;}return 0;
}
2070
题目
思路
先计算并存储斐波那契数列的前 51 项,然后通过循环不断读取用户输入的项数,输出对应的斐波那契数列的值,直到用户输入 -1 为止。这种预先计算并存储的方式可以避免每次查询都重新计算斐波那契数列,提高了程序的运行效率。
1. 宏定义与数组定义
#define int long long
:使用宏定义将int
类型替换为long long
类型,目的是为了能够处理更大范围的整数,因为斐波那契数列增长较快,使用long long
可以减少数据溢出的风险。int a[51];
:定义一个长度为 51 的整数数组a
,用于存储斐波那契数列的前 51 项(从第 0 项到第 50 项)。2. 计算斐波那契数列的前 51 项
使用
for
循环从第 2 项开始计算斐波那契数列的每一项。斐波那契数列的递推公式为 F(n)=F(n−1)+F(n−2)(其中 n≥2),因此通过数组中前两项的值相加得到当前项的值,并存储在数组a
中。
代码
#include<iostream>
using namespace std;
#define int long long
int a[51];
signed main(){int n;a[0]=0;a[1]=1;for(int i=2;i<=50;i++){a[i]=a[i-2]+a[i-1];}while(cin>>n){if(n==-1) {//cout<<"you can use 64bit integer: __int64";break;}cout<<a[n]<<endl;}return 0;
}
2071
题目
思路
过循环读取多组数据,对每组数据进行降序排序后输出最大值,并保留两位小数。通过使用
vector
容器和sort
函数,实现了动态存储和排序的功能。循环处理每组数据
- 使用
for
循环,循环次数为n
,每次循环处理一组数据。vector<int> aaaa;
:在每次循环开始时,创建一个vector
容器aaaa
,用于存储当前组的浮点数。cin>>m;
:读取当前组数据中浮点数的个数m
。- 嵌套的
for
循环读取m
个浮点数,并将它们依次添加到aaaa
容器中。对每组数据进行降序排序
使用
sort
函数对aaaa
容器中的元素进行降序排序。rbegin()
和rend()
分别返回容器的反向迭代器的起始和结束位置,通过这种方式可以实现降序排序。
代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define int double
int n,m,num;
signed main(){cin>>n;for(int i=0;i<n;i++){vector<int> aaaa;cin>>m;for(int j=0;j<m;j++){cin>>num;aaaa.push_back(num);} sort(aaaa.rbegin(),aaaa.rend());printf("%.2lf\n",aaaa[0]);aaaa.clear();} return 0;
}
2075
题目
思路
针对每组输入的两个整数,判断第一个整数是否能被第二个整数整除,并输出相应的判断结果。
代码
#include<iostream>
using namespace std;
#define int long long
int a,b,n;
signed main(){cin>>n;for(int i=0;i<n;i++){cin>>a>>b;if(a%b==0){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}}return 0;
}
2089
题目
思路
主要思路是统计在给定区间
[l, r]
内,满足特定条件的整数个数。1.预处理所有可能的整数
- 提取每一位数字:对于从 0 到 1000000 的每个整数
i
,通过while
循环将其每一位数字提取出来,并存储在vector a
中。- 检查条件:使用
flag
变量标记当前整数是否满足条件。遍历vector a
中的每一位数字,如果遇到数字4
或者连续的26
,则将flag
置为 0,表示不满足条件。- 标记结果:如果
flag
仍然为 1,则说明该整数满足条件,将aa[i]
置为 1。- 清空容器:处理完一个整数后,清空
vector a
,为下一个整数的处理做准备。2.循环读取区间并统计满足条件的整数个数
- 读取区间:使用
while
循环不断读取输入的区间[l, r]
,直到输入的l
和r
都为 0 时停止。- 统计个数:对于每个区间,遍历区间内的所有整数,检查
aa[i]
是否为 1,如果是,则说明该整数满足条件,将计数器ans
加 1。- 输出结果:输出区间内满足条件的整数个数。
代码
#include<iostream>
#include<vector>
using namespace std;
int l,r;
int aa[2000000];
vector<int> a;
int main(){for(int i=0;i<=1000000;i++){int num=i;while(num>0){int b=num%10;num/=10;a.push_back(b);}int flag=1;for(int j=0;j<a.size();j++){if(a[j]==4){flag=0;break;}if(a[j]==2 && a[j+1]==6){flag=0;break;}}if(flag) aa[i]=1;a.clear();}while(cin>>l>>r){if(l==0 && r==0) break;int ans=0;for(int i=l;i<=r;i++){if(aa[i]==1){ans++;}}cout<<ans<<endl;}return 0;
}
2090
题目
思路
主要思路是从标准输入中持续读取字符串、两个浮点数,将后两个浮点数的乘积累加到一个变量中,最后根据累加结果是否为整数来决定输出格式并输出该结果。
- 通过判断
sum
是否等于将其转换为整数后的结果(sum != (int) sum
),来确定sum
是否为整数。- 如果
sum
不是整数,使用printf
函数以保留一位小数的格式输出sum
("%.1lf"
)。- 如果
sum
是整数,使用printf
函数以整数格式(不保留小数位)输出sum
("%.0lf"
)。
代码
#include<iostream>
#include<string>
using namespace std;
string s;
double a,b,sum;
int main(){while(cin>>s>>a>>b){sum+=a*b;}if(sum!=(int) sum) printf("%.1lf",sum);else printf("%.0lf",sum);return 0;
}
2092
题目
思路
核心思路是针对多组输入的整数对
(a, b)
,判断是否存在两个整数x
和y
,使得x + y = a
且x * y = b
。注:如果纯暴力会超时
利用一元二次方程求解
根据判别式进行判断
判别式小于 0
判别式大于等于 0
代码
#include<iostream>
#include<math.h>
using namespace std;
int main(){int a,b;int flag=0;while(cin>>a>>b){if(a==0 && b==0) break;int pbs=a*a-4*b;if(pbs<0) {cout<<"No"<<endl;continue;}else{int aa=sqrt(pbs);if(aa*aa==pbs){if((-a+aa)%2==0 && (-a-aa)%2==0){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}}else{cout<<"No"<<endl;}}}return 0;
}
2096
题目
思路
主要思路是处理多组输入的整数对,对每组整数对中的两个整数进行特定处理后求和,再对求和结果进行相同处理,最后输出处理后的结果。
check
函数接收一个整数num
作为参数。- 其功能是对输入的整数进行处理,如果该整数大于或等于 100,就返回该整数除以 100 的余数,也就是取该整数的后两位;如果该整数小于 100,则直接返回该整数本身。
代码
#include<iostream>
using namespace std;
int check(int num){if(num>=100) return num%100;return num;
}
int main(){int n,a,b;cin>>n;for(int i=0;i<n;i++){cin>>a>>b;int aa=check(a);int bb=check(b);int cc=check(aa+bb);cout<<cc<<endl;}return 0;
}