当前位置: 首页 > article >正文

数字转换(c++)

【题目描述】

如果一个数 xx 的约数和 yy (不包括他本身)比他本身小,那么 xx 可以变成 yy ,yy 也可以变成 xx 。例如 44 可以变为 33 ,11 可以变为 77 。限定所有数字变换在不超过 nn 的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。

【输入】

输入一个正整数 nn 。

【输出】

输出不断进行数字变换且不出现重复数字的最多变换步数。

【输入样例】

7

【输出样例】

3

【提示】

样例说明

一种方案为 4→3→1→74→3→1→7 。

数据范围与提示:

对于 100100 的数据,1≤n≤500001≤n≤50000 。

#include<bits/stdc++.h>
using namespace std;
const int N = 50010, M = 2 * N;
int h[N], e[N], ne[M], idx;
int sum[N];
bool st[N]; //记录树根
int n;
int ans;
void add(int a, int b) {
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx++;
}//a,b间加边(a单加b边)
int dfs(int u) {
	int d1 = 0, d2 = 0;//最长 次长 
	for (int i = h[u]; i != -1; i = ne[i]) {//枚举所有u的下一个节点 
		int j = e[i];//下一个节点 
		int d = dfs(j) + 1;//找到各种的最长值 
		if (d >= d1) d2 = d1, d1 = d;
		else if (d > d2) d2 = d;//改变最大次大 
	}
	ans = max(ans, d1 + d2);//最大答案 
	return d1;//返回最长值 
}
int main() {
	cin >> n;
	memset(h, -1, sizeof h);
	for (int i = 1; i <= n; i++) {
		for (int j = 2; j <= n / i; j++) {
			sum[j * i] += i;
		}
	}//求每个数的约数和 
	for (int i = 2; i <= n; i++) {
		if (i > sum[i]) {
			add(sum[i], i);//y->x
			st[i] = true;//x可以作为根 
		}//约数和比自身小
	}
	for (int i = 1; i <= n; i++) {
		if (!st[i]) {//i不能作为根 
			dfs(i);
		}
	}
	cout << ans << endl;
	return 0;
}


http://www.kler.cn/a/611224.html

相关文章:

  • 导出sql命令
  • 卡尔曼滤波入门(二)
  • 【C++网络编程】第5篇:UDP与广播通信
  • 蓝桥杯 R格式
  • K8S学习之基础四十三:k8s中部署elasticsearch
  • 保姆级教程 在linux上启动Docker并且使用IntelliJ DockerCompose一键部署Springboot应用 常见命令
  • C语言-适配器模式详解与实践
  • 技术迭代、流量困境与营销突破:基于开源AI大模型与S2B2C模式的创新路径研究
  • Rust从入门到精通之进阶篇:11.所有权系统详解
  • 第十一节 MATLAB关系运算符
  • 电动自行车/电动工具锂电池PCM方案--SH367003、SH367004、SH79F329
  • 深度分页优化思路
  • C++ 多线程简要讲解
  • Modbus RTU ---> Modbus TCP透传技术实现(Modbus透传、RS485透传、RTU透传)分站代码实现、协议转换器
  • Postman 下载文件指南:如何请求 Excel/PDF 文件?
  • 2025BAT大厂Java面试2000题精选(附答案+考点分析)
  • 人员进出新视界:视觉分析算法的力量
  • 淘宝获取商品sku详情API接口如何调用?
  • 前端学习笔记--CSS
  • vue vue3 走马灯Carousel