【牛客想开了大赛2 B】n的约数【打表】

博客围绕一个算法问题展开,题目为t次询问,每次给定数n,求[1,n]内约数个数最多的数的约数个数。解题思路是打表,此为经典反素数问题,在1018范围内符合条件的数字仅156个,可通过OEIS找表,还给出了具体操作步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

题目链接:https://ac.nowcoder.com/acm/contest/907/B
t t t次询问,每次给你一个数 n n n,求在 [ 1 , n ] [1,n] [1,n]内约数个数最多的数的约数个数。


思路:

打表。
[ 1 , n ] [1,n] [1,n]内约数个数最多的数就是经典的反素数问题。
通过OEIS发现,这样的数字在 1 0 18 10^{18} 1018范围内只有156个。

然后OEIS都是会有表的
在这里插入图片描述
而这156个数字就是小于等于 1 0 18 10^{18} 1018的约数个数最多的数字。

string a[158]={"0","1","2","4","6","12","24","36","48","60","120","180","240","360","720","840","1260","1680","2520","5040","7560","10080","15120","20160","25200","27720","45360","50400","55440","83160","110880","166320","221760","277200","332640","498960","554400","665280","720720","1081080","1441440","2162160","2882880","3603600","4324320","6486480","7207200","8648640","10810800","14414400","17297280","21621600","32432400","36756720","43243200","61261200","73513440","110270160","122522400","147026880","183783600","245044800","294053760","367567200","551350800","698377680","735134400","1102701600","1396755360","2095133040","2205403200","2327925600","2793510720","3491888400","4655851200","5587021440","6983776800","10475665200","13967553600","20951330400","27935107200","41902660800","48886437600","64250746560","73329656400","80313433200","97772875200","128501493120","146659312800","160626866400","240940299600","293318625600","321253732800","481880599200","642507465600","963761198400","1124388064800","1606268664000","1686582097200","1927522396800","2248776129600","3212537328000","3373164194400","4497552259200","6746328388800","8995104518400","9316358251200","13492656777600","18632716502400","26985313555200","27949074753600","32607253879200","46581791256000","48910880818800","55898149507200","65214507758400","93163582512000","97821761637600","130429015516800","195643523275200","260858031033600","288807105787200","391287046550400","577614211574400","782574093100800","866421317361600","1010824870255200","1444035528936000","1516237305382800","1732842634723200","2021649740510400","2888071057872000","3032474610765600","4043299481020800","6064949221531200","8086598962041600","10108248702552000","12129898443062400","18194847664593600","20216497405104000","24259796886124800","30324746107656000","36389695329187200","48519593772249600","60649492215312000","72779390658374400","74801040398884800","106858629141264000","112201560598327200","149602080797769600","224403121196654400","299204161595539200","374005201994424000","448806242393308800","673209363589963200","748010403988848000","897612484786617600","999999999999999999999999"};

然后把前面几个最小的数字拿出来,暴力算出它的约数个数。

#include <cstdio>
#include <iostream>

int cnt,n;

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		if (!(n%i)) cnt++;
	printf("%d\n",cnt);
	return 0;
}

然后把这些数字再次放到OEIS
找到的前156个数字

string b[157]={"0","1","2","3","4","6","8","9","10","12","16","18","20","24","30","32","36","40","48","60","64","72","80","84","90","96","100","108","120","128","144","160","168","180","192","200","216","224","240","256","288","320","336","360","384","400","432","448","480","504","512","576","600","640","672","720","768","800","864","896","960","1008","1024","1152","1200","1280","1344","1440","1536","1600","1680","1728","1792","1920","2016","2048","2304","2400","2688","2880","3072","3360","3456","3584","3600","3840","4032","4096","4320","4608","4800","5040","5376","5760","6144","6720","6912","7168","7200","7680","8064","8192","8640","9216","10080","10368","10752","11520","12288","12960","13440","13824","14336","14400","15360","16128","16384","17280","18432","20160","20736","21504","23040","24576","25920","26880","27648","28672","28800","30720","32256","32768","34560","36864","40320","41472","43008","46080","48384","49152","51840","53760","55296","57600","61440","62208","64512","65536","69120","73728","80640","82944","86016","92160","96768","98304","103680"};

然后就可以暴力求了。


代码:

#include <string>
#include <iostream>
using namespace std;

string a[158]={"0","1","2","4","6","12","24","36","48","60","120","180","240","360","720","840","1260","1680","2520","5040","7560","10080","15120","20160","25200","27720","45360","50400","55440","83160","110880","166320","221760","277200","332640","498960","554400","665280","720720","1081080","1441440","2162160","2882880","3603600","4324320","6486480","7207200","8648640","10810800","14414400","17297280","21621600","32432400","36756720","43243200","61261200","73513440","110270160","122522400","147026880","183783600","245044800","294053760","367567200","551350800","698377680","735134400","1102701600","1396755360","2095133040","2205403200","2327925600","2793510720","3491888400","4655851200","5587021440","6983776800","10475665200","13967553600","20951330400","27935107200","41902660800","48886437600","64250746560","73329656400","80313433200","97772875200","128501493120","146659312800","160626866400","240940299600","293318625600","321253732800","481880599200","642507465600","963761198400","1124388064800","1606268664000","1686582097200","1927522396800","2248776129600","3212537328000","3373164194400","4497552259200","6746328388800","8995104518400","9316358251200","13492656777600","18632716502400","26985313555200","27949074753600","32607253879200","46581791256000","48910880818800","55898149507200","65214507758400","93163582512000","97821761637600","130429015516800","195643523275200","260858031033600","288807105787200","391287046550400","577614211574400","782574093100800","866421317361600","1010824870255200","1444035528936000","1516237305382800","1732842634723200","2021649740510400","2888071057872000","3032474610765600","4043299481020800","6064949221531200","8086598962041600","10108248702552000","12129898443062400","18194847664593600","20216497405104000","24259796886124800","30324746107656000","36389695329187200","48519593772249600","60649492215312000","72779390658374400","74801040398884800","106858629141264000","112201560598327200","149602080797769600","224403121196654400","299204161595539200","374005201994424000","448806242393308800","673209363589963200","748010403988848000","897612484786617600","999999999999999999999999"};        
string b[157]={"0","1","2","3","4","6","8","9","10","12","16","18","20","24","30","32","36","40","48","60","64","72","80","84","90","96","100","108","120","128","144","160","168","180","192","200","216","224","240","256","288","320","336","360","384","400","432","448","480","504","512","576","600","640","672","720","768","800","864","896","960","1008","1024","1152","1200","1280","1344","1440","1536","1600","1680","1728","1792","1920","2016","2048","2304","2400","2688","2880","3072","3360","3456","3584","3600","3840","4032","4096","4320","4608","4800","5040","5376","5760","6144","6720","6912","7168","7200","7680","8064","8192","8640","9216","10080","10368","10752","11520","12288","12960","13440","13824","14336","14400","15360","16128","16384","17280","18432","20160","20736","21504","23040","24576","25920","26880","27648","28672","28800","30720","32256","32768","34560","36864","40320","41472","43008","46080","48384","49152","51840","53760","55296","57600","61440","62208","64512","65536","69120","73728","80640","82944","86016","92160","96768","98304","103680"};
string s;
int t;

bool check(string s1,string s2)
{
	if (s1.size()<s2.size()) return 1;
	if (s1.size()>s2.size()) return 0;
	for (int i=0;i<s1.size();i++)
	{
		if (s1[i]>s2[i]) return 0;
		if (s1[i]<s2[i]) return 1;
	}
	return 0;
}

int main()
{
	cin>>t;
	while (t--)
	{
		cin>>s;
		for (int i=1;i<=157;i++)
			if (check(s,a[i]))
			{
				cout<<b[i-1]<<endl;
				break;
			}
	}
	return 0;
}
### 牛客 BM2 的 C++ 实现 BM2 是一道经典的算法题目,主要涉及二叉树的最大路径和问题。以下是基于已知信息以及常见解决思路给出的 C++ 实现。 #### 方法概述 该问题可以通过 **动态规划** 和 **递归回溯** 来求解。核心思想是从根节点出发,计算经过任意节点的最大路径和。对于每一个节点,其贡献可以分为两种情况: 1. 节点作为路径的一部分(单边向下延伸)。 2. 节点成为路径的转折点(左子树 + 右子树 + 当前节点值)。 最终通过递归的方式自底向上更新全局最大值。 --- #### C++ 实现代码 ```cpp /** * Definition for a binary tree node. */ struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; class Solution { public: int maxPathSum(TreeNode* root) { if (!root) return INT_MIN; // 边界条件处理 int globalMax = INT_MIN; helper(root, globalMax); return globalMax; } private: int helper(TreeNode* node, int& globalMax) { if (!node) return 0; // 左右子树的最大贡献值,忽略负数部分 int leftGain = std::max(helper(node->left, globalMax), 0); int rightGain = std::max(helper(node->right, globalMax), 0); // 更新当前节点为路径转折点时的最大值 int currentMax = node->val + leftGain + rightGain; globalMax = std::max(globalMax, currentMax); // 返回以当前节点为起点的一侧最大路径和 return node->val + std::max(leftGain, rightGain); } }; ``` --- #### 关键点解析 1. **递归函数设计** - `helper` 函数用于计算以某个节点为根的最大路径和,并将其结果存储到 `globalMax` 中。 - 对于每个节点,分别考虑左侧和右侧子树的最大贡献值[^3]。 2. **边界条件** - 如果当前节点为空,则返回 0 表示无贡献。 - 使用 `INT_MIN` 初始化全局变量 `globalMax`,确保能够正确记录最小可能值。 3. **优化细节** - 避免重复计算子树的最大路径和,利用递归特性一次完成所有节点的访问。 --- #### 时间与空间复杂度分析 - **时间复杂度**: O(n),其中 n 是二叉树中节点的数量。每个节点仅被访问一次。 - **空间复杂度**: O(h),h 是二叉树的高度。最坏情况下(退化成链表),空间复杂度为 O(n)[^3]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值