杭电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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值