灰魔法师

题目背景

“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以内的所有完全平方数,标记上,枚举 ij ,符合条件就计入答案。时间复杂度为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\n",ans/2);
      return 0;
}

猜你喜欢

转载自www.cnblogs.com/Princeoftheking/p/9860799.html
今日推荐