Wannafly挑战赛27 A-灰魔法师(思维)

 

题目链接:https://www.nowcoder.com/acm/contest/215/A

       这道题暴力肯定是过不了的,然后就有一种很巧妙地方法,因为数据范围只有1e5,两个数相加最大也只有2e5,然后2e5的数据中,完全平方数的个数其实只有几百个,所以我们可以将2e5范围内的完全平方数先打个表存起来,然后对于输入的n个数,我们只需要记录它出现的个数,然后我们去枚举1-100000中的数。

       对于接下来的操作,分为两种情况,一种是2 2 2,对于有3个2的情况,它符合条件的个数为3(就是3*(3-1)/2),另一种情况是1 1 3 3,这样的话符合情况的个数就是2(因为不能重复),这种情况的解就是pre[1] * pre[3] / 2。所以我们只需要对于这两种情况讨论就行了。

       还有一个小坑点就是在第二种情况的时候,我们要先把所有的第二种情况算出来以后再除以2,不然会有精度损失(详细看呆码),还有改用ll的地方记得用ll。

       有一点不太明白不知道为啥我的num不能从0开始,这一点wa了n发...很巧妙的一道题...


AC代码:

#include <bits/stdc++.h>
#define maxn 100000
#define ll long long
using namespace std;
int pre[maxn],a[maxn];
int n,num;
  
int main()
{
  scanf("%d",&n);
  num = 1;    // 不知道为啥不能从0开始...
  for(int i=1;i*i<=200000;i++){
    a[num++] = i * i;
  }
  memset(pre,0,sizeof(pre));
  for(int i=0;i<n;i++){
    int x;
    scanf("%d",&x);
    pre[x] ++;
  }
  ll sum = 0,sum1 = 0;
  for(int i=1;i<=num;i++){
    for(int j=1;j<=maxn;j++){
      if(pre[j] == 0) continue;
      int ans = a[i] - j;
      if(ans > maxn) continue;
      if(ans <= 0) break;
      if(pre[ans]){
        if(ans == j) sum1 += ((ll)pre[j] * (ll)(pre[j] - 1)) / 2;
        else sum += (ll)pre[ans] * (ll)pre[j];    // 这里不要除以2,会有精度损失
      }
    }
  }
  printf("%lld\n",sum1 + sum / 2);
  return 0;
}

 

全部评论

相关推荐

02-25 16:55
已编辑
北京工业大学 Java
211本,找日常实习的话,如果面向中厂的话,需要刷hot100么?因为之前从来没刷过,算法仅限于学校课程水平,准备3月投递简历,现在还需要背八股文,时间有些紧张,还需要刷算法题么?同时什么样的公司可以算是中厂呢?
程序员小白条:中大厂说的上名字的,必定要算法,hot100只是最基础的了,题库远不止100题捏,一般在300-400题量之间,算法=学校课程=简单题也做不出,多准备八股文和算法吧,其他项目可以放放,精刷算法就行了,花时间成长很快的
点赞 评论 收藏
分享
白火同学:先说结论,对于一份实习简历来说,整体还是挺不错的,技术深度和广度都到位,找到一份中小厂的实习没啥问题。 再说说能优化的点吧。 1、量化结果,项目中很多工作量化一下结果给面试官的感受会更直观一些,也能体现你对应用该项技术的理解(在众多技术为什么要用它,运行性能或者说开发效率往往是一大考虑指标;而不是说大家做这种功能都用它,所以我用它)。 2、突出亮点,项目中可以从“工作职责”择一些“个人亮点”另写一块,优先去写开发过程中遇到的xx问题,使用xx技术达到xx效果,针对性去写一些疑杂难的功能,能带出你个人思考和解决的过程。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务