洛谷P11919 [PA 2025] 水族馆 / Akwarium 题解

题目链接

题后感想

这道题属实是一道很好的思维题,让我长眼界了,必须发篇题解分享一下我的做题历程。

题目大意

题目的大意是求 \(a^2+b^2+h^2 = k(k \le n)\) 的满足条件的 \(a\)\(b\)\(h\) 的不同取值的情况数量。

思路及代码

思路一:暴力不动脑

由题目不难想到直接三重循环枚举 \(k\)\(a\)\(b\),在判断 \(k-a-b\)\(h^2\) 的值是否满足为完全平方数,再进行统计即可,时间复杂度为 \(O(n^3)\),最高可得 \(90\) 分。

思路一代码实现

#include<bits/stdc++.h>
using namespace std;
int ans,n,x,a,b,t;
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;++i)
	{
		x=i*i;
		for(int j=1;j<i;++j)
		{
			a=j*j;
			for(int k=j;k<i;++k)
			{
				b=k*k;
				if(a+b>=x)break;
				t=int(sqrt(x-a-b));
				if(x-a-b==t*t)
				{
					ans++;
				}
			}
		}
	}
	cout<<ans;
    return 0;
}

然而我一开始到了这一步时,分数就一直停滞不前,最后一组捆绑数据一直超时。

当我迷茫之时,楼下第一篇题解的出现犹如一阵风吹散了我思维上的迷雾,于是我得出了思路二。

思路二:巧妙拆分省时间

我们只要预先计算出 \(1\)\(n^2\) 中所有数拆分成 \(a^2+b^2\) 的所有情况用数组统计,用别的会炸时间,这是血的教训。

再只用双重循环枚举 \(h\)\(k\) 即可,判断 \(k^2-h^2\) 是否为完全平方数,如是,则加上该数所有的 \(a^2+b^2\) 的拆分情况即可得出最终答案。

时间复杂度为 \(O(n^2)\),可得 \(100\) 分。

思路二代码实现

#include<bits/stdc++.h>
using namespace std;
int ans,n,x,a,b,t,p[25000005];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;++i)
	{
		x=i*i;
		for(int j=i;j<=n;++j)
		{
			a=j*j;
			p[a+x]++;
		}
	}
	for(int i=1;i<=n;++i)
	{
		a=i*i;
		for(int j=1;j<i;++j)
		{
			x=j*j;
			if(a>x&&p[a-x])ans+=p[a-x];
		}
	}
	cout<<ans;
	return 0;
}

如有问题请直接提出,我会改进该篇题解。

最后感谢您的留步与观看,希望本篇题解能够帮到您。

posted @ 2025-07-14 20:10  xianxi_zx  阅读(22)  评论(0)    收藏  举报