牛客Wannafly挑战赛27 A 灰魔法师

本文解析了一种寻找数组中完全平方数对的算法。通过预处理生成完全平方数列表,利用数组记录输入序列,遍历查找满足条件的数对,解决组合计数问题。特别讨论了重复元素的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感谢大佬%%%
↑↑↑↑↑↑↑↑↑↑
讲解非常仔细

做题的时候也有想过去打表,然后就没有了,
还是没有找到其中的规律。。。。
这里补一条完全平方数的定义?
这个数开根号后是整数 如:9,25,36…

思路:

因为题目数据是1e5,所以两个数相加也只有2e5,从1到2e5满足条件的完全平方数个数也只有400+,就用一个数组去记录下来,然后for循环把给出的序列先标记一遍,再从已知的完全平方数里挨个for一遍找到:
完全平方数 减去 a[i]得到一个数,这个数是否存在所给序列中
存在的话就会出现两种情况:

  1. 如2 2 2这种情况就有三种方案 其实就是组合数的公式,
    (n个数里选两个):n×(n-1)/2;
  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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值