欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。
题目链接:http://iai.sh.cn/problem/612
题目解析
先对原式进行两边开根号:
A
+
B
=
C
,
可
分
解
C
=
n
⋅
m
,
m
是
不
包
含
完
全
平
方
因
子
的
数
\sqrt A + \sqrt B = \sqrt C, 可分解\sqrt C = n\cdot \sqrt m,m是不包含完全平方因子的数
A+B=C,可分解C=n⋅m,m是不包含完全平方因子的数
从上式以推断出什么情况下成立。
当 a m + b m , 只 有 开 根 号 里 的 数 字 是 相 同 的 , 才 可 以 相 加 。 当a\sqrt m + b \sqrt m, 只有开根号里的数字是相同的,才可以相加。 当am+bm,只有开根号里的数字是相同的,才可以相加。
基本思路就是枚举m(不包含完全平方因子的数)。
计算a, b的个数。
a个数计算过程:
a
2
∗
m
<
=
q
(
q
是
题
目
给
定
的
已
知
量
)
,
a
<
=
q
/
m
,
既
q
/
m
就
是
a
可
取
值
的
数
目
,
b
也
同
理
,
相
乘
就
是
以
m
开
根
号
的
情
况
下
的
方
法
数
。
a^2*m<= q(q是题目给定的已知量), a<=\sqrt{q/m}, \\ 既\sqrt{q/m}就是a可取值的数目,\\ b也同理,相乘就是以m开根号的情况下的方法数。
a2∗m<=q(q是题目给定的已知量),a<=q/m,既q/m就是a可取值的数目,b也同理,相乘就是以m开根号的情况下的方法数。
步骤:
- 先筛选出所有 m(不包含完全平方因子的数)。
- 枚举所有m, 计算出a, b相乘加到答案中。
AC代码
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 1e6+10;
typedef long long lld;
lld isMult[2*N];
void Init(int n) {
memset(isMult, 0, sizeof(isMult));
for(int i=2;i<=sqrt(n);i++) {
for(int s = i*i;s<=n;s+=i*i) isMult[s]=true; // 只是一个完全平方数的倍数都标记
}
}
int countP(int n, int p) {
int ans = 0;
while(n%p==0){
ans++;
n/=p;
}
return ans;
}
// 奇数 0 0, 1 1, 2 1, 3 2
int getOdd(int c) {
if(c==0)return 0;
return (c-1)/2+1;
}
// 偶数
int getEven(int c) {
return c/2+1;
}
void solve()
{
int n, m;
cin>>n>>m;
Init(max(n, m));
lld ans = 0;
for(int i=1;i<=n && i<=m;i++) {
if(isMult[i])continue; // 是完全平方数,不需要计数
int a = sqrt(n/i); // 计算出可枚举的整数部分
int b = sqrt(m/i);
ans += a*b; // 加入答案中
}
cout<<ans<<endl;
}
int main()
{
solve();
return 0;
}
/*
5 5
1 1 4
2 2
3 3
4 1 4
5 5
*/
本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。