感谢大佬%%%
↑↑↑↑↑↑↑↑↑↑
讲解非常仔细
做题的时候也有想过去打表,然后就没有了,
还是没有找到其中的规律。。。。
这里补一条完全平方数的定义?
这个数开根号后是整数 如:9,25,36…
思路:
因为题目数据是1e5,所以两个数相加也只有2e5,从1到2e5满足条件的完全平方数个数也只有400+,就用一个数组去记录下来,然后for循环把给出的序列先标记一遍,再从已知的完全平方数里挨个for一遍找到:
完全平方数 减去 a[i]得到一个数,这个数是否存在所给序列中
存在的话就会出现两种情况:
- 如2 2 2这种情况就有三种方案 其实就是组合数的公式,
(n个数里选两个):n×(n-1)/2;- 如1 1 3 3这里就会重复计算,因为起初是从1开始去找3,在3的时候又去找1,所以ans/=2;
大概就是这样了
代码是dalao那搬运的
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll vis[100010],n,a[1010],pos,ans1,ans2;
ll ans;
int main()
{
pos=1;
for(ll i=1;i*i<=200000;i++)a[pos++]=i*i; //生成平方数
while(~scanf("%lld",&n))
{
memset(vis,0,sizeof(vis));
ll x;
for(ll i=1;i<=n;i++)
{
scanf("%lld",&x);
vis[x]++; //统计个数
}
ans1=ans2=0;
ll tmp;
for(ll i=1;i<pos;i++) //平方数数组
{
for(ll j=1;j<=100000;j++) //1e5以内所有数
{
if(vis[j]==0)continue;
tmp=a[i]-j;
if(tmp>100000)continue; //不合法范围
if(tmp<=0)break; //不合法
if(vis[tmp])
{
if(tmp==j)ans1+=(vis[j]*(vis[j]-1))/2; //相同时用组合公式
else ans2+=vis[tmp]*vis[j]; //不同时直接乘
}
}
}
ans1=ans1+ans2/2;
printf("%lld\n",ans1);
}
return 0;
}