菜鸟生成记(26)
P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题
这一题就是考察最大公约和最小公倍;不过就是数据有点大(1e+5)暴力是过不了的;需要剪枝(就是删减掉不必要的循环);
这一题双层循环应该很难通过,蒻羁的我双循环最高80;单循环秒过
AC代码
#include<bits/stdc++.h>
using namespace std;
int fun1(int a,int b)//求最大公约数
{
if(a<b)
{
int x;
x=a;
a=b;
b=x;
}
int t,r;
r=a*b;
t=a%b;
while(t)//辗转相除
{
a=b;
b=t;
t=a%b;
}
return b;//返回最大公约数
}
void fun(int x,int y)
{
int m=max(x,y)//取值右边界
int n=min(x,y);//取值左边界
int k=0;//符合条件 计数
int sum=x*y;//
for(int i=n;i<=m;i+=n)//题上说x(n)为q,p最大公约数,所以将i的增量设为n(减少不必要的遍历)
{
int s=fun1(i,sum/i);//最大公约数
if(i*(sum/i)==sum&&s==x&&sum/s==y)//最小公倍数==x*y/最大公约数
{
k++;//符合条件计数
//cout<<i<<" "<<sum/i<<endl;
}
}
cout<<k;
}
int main()
{
int x,y;
cin>>x>>y;
fun(x,y);
return 0;
}
80分代码(超时)( 双循环实在改不动了,我稍改一下就错的更多了T-T)
#include<bits/stdc++.h>
using namespace std;
int fun1(int a,int b)
{
if(a<b)
{
int x;
x=a;
a=b;
b=x;
}
int t,r;
r=a*b;
t=a%b;
while(t)
{
a=b;
b=t;
t=a%b;
}
return b;
}
void fun(int x,int y)
{
int m=max(x,y),n=min(x,y),k=0;
int sum=x*y;
for(int i=n;i<=m;i+=n)
{
for(int j=n;j<=m;j+=n)
{
if(i*j==sum&&fun1(i,j)==x&&(i*j)/fun1(i,j)==y)
{
k++;
//cout<<i<<" "<<j<<endl;
}
}
}
cout<<k;
}
int main()
{
int x,y;
cin>>x>>y;
fun(x,y);
return 0;
}