记录28
#include <bits/stdc++.h>
using namespace std;
int f(int x){
int sum=0;
for(int i=1;i<x;i++){
if(x%i==0) sum+=i;
}
return sum;
}
int main(){
int s;
cin>>s;
for(s;;s++){
if(f(f(s))==s&&s!=f(s)){
cout<<s<<" "<<f(s);
break;
}
}
return 0;
}
突破点
如果 A 的序列号的约数之和恰好等于 B 的序列号,那么 A 的好朋友就是 B。
👉一个数的约数和等于另一个数
在这里,一个数的约数不包括这个数本身👉没说不包括1
当两个同学互为“好朋友”时,他们就是一对“非常好友” 👉两个数的约数和互为对方
给定一个序列号 s,找出序列号不小于 s 的第一对“非常好友”
👉从输入的数开始找两个约数和互为对方的数
思路
- 写一个求约数和的函数
- 枚举数字,找到后输出
代码简析
int f(int x){
int sum=0;
for(int i=1;i<x;i++){
if(x%i==0) sum+=i;
}
return sum;
}
对一个数求约数,就是对这个数取余为0
注意:题目只说不包括自身,记得从一开始
#include <bits/stdc++.h>
using namespace std;
int f(int x){
...
...
}
int main(){
int s;
cin>>s;
for(s;;s++){
if(f(f(s))==s&&s!=f(s)){
cout<<s<<" "<<f(s);
break;
}
}
return 0;
}
两个数的约数之和,互相为对方
s为输入的数,从这个数开始筛选,寻找A跟B两个非常好友
即B=f(A),A=f(B),所以A=f(f(A))
注意:AB是两个不同的数,所以A不等于B,即s!=f(s)
补充
1. 约数的定义
定义:如果一个整数 a 能够被另一个整数 b 整除,即 amodb=0,那么 b 是 a 的约数(因数)。
2. 常用处理约数的手段
2.1 枚举法
定义:通过遍历所有可能的数来找到一个数的所有约数。
适用场景:适用于较小的数,因为时间复杂度较高。
时间复杂度:O(
),其中 n 是目标数。
示例代码
#include <iostream> #include <vector> using namespace std; vector<int> getDivisors(int n) { vector<int> divisors; for (int i = 1; i * i <= n; ++i) { if (n % i == 0) { divisors.push_back(i); if (i != n / i) { // 避免重复添加平方根 divisors.push_back(n / i); } } } return divisors; } int main() { int n; cout << "请输入一个整数:"; cin >> n; vector<int> divisors = getDivisors(n); cout << n << " 的约数有:"; for (int d : divisors) { cout << d << " "; } cout << endl; return 0; }2.2 筛法
定义:使用筛法预先计算出一定范围内的所有约数。
适用场景:适用于需要多次查询多个数的约数的情况。
时间复杂度:O(nloglogn),其中 n 是目标范围。
示例代码
#include <iostream> #include <vector> using namespace std; const int MAXN = 100005; vector<int> divisors[MAXN]; void sieve(int n) { for (int i = 1; i <= n; ++i) { for (int j = i; j <= n; j += i) { divisors[j].push_back(i); } } } int main() { int n; cout << "请输入一个整数:"; cin >> n; sieve(n); cout << n << " 的约数有:"; for (int d : divisors[n]) { cout << d << " "; } cout << endl; return 0; }2.3 质因数分解
定义:将一个数分解为质因数的乘积。
适用场景:适用于需要处理较大数的约数问题。
时间复杂度:O(
),其中 n 是目标数。
示例代码
#include <iostream> #include <vector> using namespace std; vector<pair<int, int>> primeFactorization(int n) { vector<pair<int, int>> factors; for (int i = 2; i * i <= n; ++i) { if (n % i == 0) { int count = 0; while (n % i == 0) { n /= i; ++count; } factors.push_back({i, count}); } } if (n > 1) { factors.push_back({n, 1}); } return factors; } int main() { int n; cout << "请输入一个整数:"; cin >> n; vector<pair<int, int>> factors = primeFactorization(n); cout << n << " 的质因数分解为:"; for (auto& factor : factors) { cout << factor.first << "^" << factor.second << " "; } cout << endl; return 0; }2.4 欧几里得算法
定义:用于计算两个数的最大公约数(GCD)。
适用场景:适用于需要处理多个数的公约数问题。
时间复杂度:O(logmin(a,b)),其中 a 和 b 是目标数。
示例代码
#include <iostream> using namespace std; int gcd(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } int main() { int a, b; cout << "请输入两个整数:"; cin >> a >> b; cout << "最大公约数是:" << gcd(a, b) << endl; return 0; }2.5 约数个数和约数和
定义:通过质因数分解计算约数个数和约数和。
适用场景:适用于需要计算约数个数和约数和的问题。
时间复杂度:O(
),其中 n 是目标数。
示例代码
#include <iostream> #include <vector> using namespace std; vector<pair<int, int>> primeFactorization(int n) { vector<pair<int, int>> factors; for (int i = 2; i * i <= n; ++i) { if (n % i == 0) { int count = 0; while (n % i == 0) { n /= i; ++count; } factors.push_back({i, count}); } } if (n > 1) { factors.push_back({n, 1}); } return factors; } int main() { int n; cout << "请输入一个整数:"; cin >> n; vector<pair<int, int>> factors = primeFactorization(n); // 计算约数个数 int numDivisors = 1; for (auto& factor : factors) { numDivisors *= (factor.second + 1); } // 计算约数和 long long sumDivisors = 1; for (auto& factor : factors) { long long sum = 1; long long p = 1; for (int i = 0; i < factor.second; ++i) { p *= factor.first; sum += p; } sumDivisors *= sum; } cout << n << " 的约数个数是:" << numDivisors << endl; cout << n << " 的约数和是:" << sumDivisors << endl; return 0; }3. 总结
枚举法:适用于较小的数,时间复杂度为 O(
)。
筛法:适用于需要多次查询多个数的约数的情况,时间复杂度为 O(nloglogn)。
质因数分解:适用于需要处理较大数的约数问题,时间复杂度为 O(
)。
欧几里得算法:用于计算两个数的最大公约数,时间复杂度为 O(logmin(a,b))。
约数个数和约数和:通过质因数分解计算约数个数和约数和,时间复杂度为 O(
)。
1038

被折叠的 条评论
为什么被折叠?



