[GESP202506 六级] 最大因数(含视频)

视频讲解:GESP202506 六级 最大因数-信息学奥赛GESP等级考试真题解析

一、原题

题目描述

给定一棵有 10^9 个结点的有根树,这些结点依次以 1,2,...,10^9 编号,根结点的编号为 1。对于编号为 k(2≤k≤10^9)的结点,其父结点的编号为 k 的因数中除 k 以外最大的因数。

现在有 q 组询问,第 i(1≤i≤q)组询问给定 xi​,yi​,请你求出编号分别为 xi​,yi​ 的两个结点在这棵树上的距离。两个结点之间的距离是连接这两个结点的简单路径所包含的边数。

输入格式

第一行,一个正整数 q,表示询问组数。

接下来 q 行,每行两个正整数 xi​,yi​,表示询问结点的编号。

输出格式

输出共 q 行,每行一个整数,表示结点 xi​,yi​ 之间的距离。

输入输出样例

输入 #1

复制代码
3
1 3
2 5
4 8

输出 #1

复制代码
1
2
1

输入 #2

复制代码
1
120 650

输出 #2

复制代码
9

说明/提示

对于 60% 的测试点,保证 1≤xi​,yi​≤1000。

对于所有测试点,保证 1≤q≤1000,1≤xi​,yi​≤10^9。

二、做题思路

1)填充数据

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	//1)填充数据
	//1.1)确定组数q
	int q;cin>>q; 
	//1.2)填充q组询问编号
	for(int i=1;i<=q;i++){
		int x,y;
		cin>>x>>y;
	}
	return 0; 
}

2)标记所有最大因数,以及位置

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
void cal(int x){
	//2.2)标记当前数字 
	int now=0;
	dict[x].push_back(now);
	if(x==1) return ;//1标记后直接退出 
	//2.3)寻找当前最小因数,同时记录出现位置 
	for(int i=2;i*i<=x;i++){
		//16(8)  8(4)  4(2)  2(1)  1
		while(x%i==0&&x!=i){
			//2.4)标记对应的大因数的出现位置 
			x/=i;
			now++;
			dict[x].push_back(now);
		}
	}
	//2.5)1也需要标记
	now++;
	dict[1].push_back(now);
}
int main(){
	//1)填充数据
	//1.1)确定组数q
	int q;cin>>q; 
	//1.2)填充q组询问编号
	for(int i=1;i<=q;i++){
		int x,y;
		cin>>x>>y;
		//2.1)清除上一次,函数开始计算
		dict.clear(); 
		cal(x),cal(y);
	}
	
	return 0; 
}

3)找标记2次的最大值,输出结果

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>>dict;
void cal(int x){
	/....
}
int main(){
	//1)填充数据
	//1.1)确定组数q
	int q;cin>>q; 
	//1.2)填充q组询问编号
	for(int i=1;i<=q;i++){
		int x,y;
		cin>>x>>y;
		//2)标记所有最大因数,以及位置 
		//...
		//3)找标记2次的最大值
		int ans=INT_MAX;
		for(auto it:dict){
			if(it.second.size()==2){
				ans=min(ans,it.second[0]+it.second[1]);
			}
		} 
		//4)输出结果 
		cout<<ans<<endl;
	}
	return 0; 
}

三、答案

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
void cal(int x){
	//2.2)标记当前数字 
	int now=0;
	dict[x].push_back(now);
	if(x==1) return ;//1标记后直接退出 
	//2.3)寻找当前最小因数,同时记录出现位置 
	for(int i=2;i*i<=x;i++){
		//16(8)  8(4)  4(2)  2(1)  1
		while(x%i==0&&x!=i){
			//2.4)标记对应的大因数的出现位置 
			x/=i;
			now++;
			dict[x].push_back(now);
		}
	}
	//2.5)1也需要标记
	now++;
	dict[1].push_back(now);
}
int main(){
	//1)填充数据
	//1.1)确定组数q
	int q;cin>>q; 
	//1.2)填充q组询问编号
	for(int i=1;i<=q;i++){
		int x,y;
		cin>>x>>y;
		//2.1)清除上一次,函数开始计算
		dict.clear(); 
		cal(x),cal(y);
	}
	return 0; 
}
相关推荐
nm_zfyjt10 分钟前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)
算法·重构·内蒙古朋友圈广告服务商·内蒙古朋友圈获客
w_zero_one1 小时前
算法--构造
java·数据结构·算法
其实防守也摸鱼2 小时前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php
小超人诞生日记3 小时前
C++ 智能指针的使用及其原理详解
c++·算法
lisw055 小时前
互联网上的数据结构可视化!
数据结构·信息可视化
AiNightVision6 小时前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件
牧羊人.3337 小时前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
小郎君6588 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie7778 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai