灰魔法师
Posted princeoftheking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了灰魔法师相关的知识,希望对你有一定的参考价值。
题目背景
“White shores, and beyond. A far green country under a swift sunrise.”--灰魔法师
题目描述
给出长度为n的序列a, 求有多少对数对 (i, j) (1 <= i < j <= n) 满足 ai + aj 为完全平方数。
输入描述
第一行一个整数 n(1 <= n <= 10^5^)
第二行 n 个整数 ai(1 <= ai <= 10^5^)
输出描述
输出一个整数,表示满足上述条件的数对个数。
思路:
第一种算法:ai + aj 最大值不会超过200000,考虑预处理出,200000以内的所有完全平方数,标记上,枚举 i 与 j ,符合条件就计入答案。时间复杂度为O(n*(n-1)/2)。
很明显过不去。
第二种算法:先预处理出每一种 ai 的个数,记为use[ ai ] 。枚举20000以内的完全平方数,对于每一个完全平方数,算出所有 ai 凑出这个完全平方数的方案数,题目中还有一个要求是1<=j<i<=n,因此将结果除以2即是答案。
代码
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘) f=0;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();}
if(f) return x;else return -x;
}
const int N=1e5+10;
int n,a[N];
long long ans;
int use[200010];
int main(){
n=read();
for(int i=1;i<=n;i++)a[i]=read(),use[a[i]]++;
for(int i=1;i*i<=200000;i++){
int now=i*i;
for(int j=1;j<=n;j++){
if(now-a[j]<0) continue;
else if(now-a[j]==a[j]) ans+=use[now-a[j]]-1;
else if(use[now-a[j]]) ans+=use[now-a[j]];
}
}
printf("%lld
",ans/2);
return 0;
}
以上是关于灰魔法师的主要内容,如果未能解决你的问题,请参考以下文章