1、阶乘约数
题目链接:阶乘约数 - 蓝桥云课
解题思路:正常情况下是先计算出 n!的大小,再枚举 1~根号n 中的数,找出并统计n的因子及因子个数,但是时间肯定不够。我们使用唯一分解定理和约数定理来解决这个问题。
唯一分解定理:每个大于1的自然数都可以分解为若干质数的乘积
其中
表示n的第i个质因子,
表示
的幂次。
约数定理:n的正约数的个数为
因此我们只需要对1~100中每个数做质因数分解,统计每个质因子的幂次,在对应相加就能得到100!的每个质因子的幂次。
分解质因数模板:
int cnt[N]; //cnt[i] 保存质因子 i的幂次
void divide (int n)
{
for (int i = 2 ; i * i <= n ; i++)
{
if (n % i == 0)
{
while (n % i ==0)
{
n /= i;
cnt[i] ++;
}
}
}
if(n > 1) cnt[n] ++; //n 是其中一个因子
}
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int cnt[N]; //cnt[i] 保存质因子 i的幂次
void divide (int n)
{
for(int i=2; i*i<=n; i++)
{
if(n%i==0)
{
while(n%i==0)
{
n/=i;
cnt[i]++;
}
}
}
if(n>1) cnt[n]++; //n是其中一个因子
}
int main()
{
int n=100;
for(int i=1;i<=n;i++)
{
divide(i);
}
//约数定理
long long ans=1;
for(int i=1;i<=n;i++)
{
if(cnt[i]!=0)
ans*=(cnt[i]+1);
}
cout<<ans<<endl;
return 0;
}
答案:39001250856960000
2、等差数列
题目链接:等差数列 - 蓝桥云课
输入示例:
5
2 6 4 10 20
输出示例:10
解题思路 : 先排序,由等差数列的性质可得 ,则计算出 d 的值之后就能求出 n 的值。d 越大,n就越小。我们记录每一项与 a1 的差值,这个差值必定是 d 的倍数,取所有差值的最大公约数,就是 d 的最大取值。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,d,a[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
d=__gcd(d,a[i]-a[1]);
}
//若d=0,则a[1]=a[2]= …=a[N]
if(!d)
cout<<n<<endl;
else
cout<<(a[n]-a[1])/d+1<<endl;
return 0;
}
3、最大比例
题目链接:最大比例 - 蓝桥云课
输入示例:
3
1250 200 32
输出示例:
25/4
解题思路:先排序,求出相邻两项之间的比,并将其约分,用两个数组分别保存其分子和分母。然后两个两个求分子和分母的最大公约数,就是答案。
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+10;
int n, cnt;
long long a[N],u[N],d[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
//排序
sort(a+1,a+1+n);
for(int i=2;i<=n;i++)
{
if(a[i]==a[i-1]) continue;
//求出相邻两项的比并约分,分子分母分开保存
long long g = __gcd(a[i],a[i-1]);
u[++cnt] = a[i]/g;
d[cnt] = a[i-1]/g;
}
//分别求最大公因子
long long x=u[1],y=d[1];
for(int i=2;i<=cnt;i++)
{
x = __gcd(x,u[i]);
y = __gcd(y,d[i]);
}
cout<<x<<"/"<<y<<endl;
return 0;
}