2019年PAT乙级秋考B-3缘分数 题型:枚举 20分 有坑点

118 阅读1分钟

1103 缘分数 - PAT (Basic Level) Practice (中文) (pintia.cn)

我刚开始写的代码是这样的:

#include<bits/stdc++.h>
using namespace std;
int m,n,flag;
int main()
{
	cin>>m>>n;
	for(int i=m;i<=n;i++)
	{
		int a=i;
		int powc=pow(a,3)-pow(a-1,3);
		int c=sqrt(powc);
	
	    	for(int j=1;j<=c/2;j++)
	    	{
	    		int b=j;
	    		if(pow(b,2)+pow(b-1,2)==c)
	    		{
	    			cout<<a<<" "<<b<<endl;
				    flag=1;
				}
			}
	}
	if(flag==0)
	{
		cout<<"No Solution\n";
	}
	return 0;
}

image.png 这其实是因为精度问题,sqrt()最后会向下取整,比如开方之后得到一个值6.5,它会自动向下取整变为6,这也导致了有些数其实没有合法,但是sqrt()让其强行合法了,如下,拿a=15,b=4举例:

image.png

因此我们需要特判一下,判断 开方后的数的乘积是否等于没开方前的值,相等了才能进行下一步:代码如下:

还要一个坑点,枚举j的时候要从2开始枚举,因为1不合法,

假设 a=b=1,虽然满足定义,但是不是缘份数,缘份数要求a!=b

#include<bits/stdc++.h>
using namespace std;
int m,n,flag;
int main()
{
	cin>>m>>n;
	for(int i=m;i<=n;i++)
	{
		int a=i;
		int powc=pow(a,3)-pow(a-1,3);
		int c=sqrt(powc);
	
	    if(c*c==powc)
	    {
	    	for(int j=1;j<=c/2;j++)
	    	{
	    		int b=j;
	    		if(pow(b,2)+pow(b-1,2)==c)
	    		{
	    			cout<<a<<" "<<b<<endl;
				    flag=1;
				}
			}
		}
	}
	if(flag==0)
	{
		cout<<"No Solution\n";
	}
	return 0;
}

image.png