1850F.We Were Both Children(Difficulty: 1300)

题目链接:

Problem - 1850F - Codeforces

 题目大致意思:

Mihai和Slavic正在观察一群青蛙,这些青蛙编号从1到n,初始位置都在点0处。青蛙i每跳一次可以跳跃ai单位长度。

每秒钟,青蛙i向前跳跃ai单位长度。在青蛙开始跳跃之前,Slavic和Mihai可以在一个坐标上放置一个陷阱,以便捕捉到所有将经过该坐标的青蛙。

然而,孩子们不能离开自己的家太远,所以他们只能在前n个点上放置陷阱(也就是坐标在1到n之间的点),并且孩子们不能在点0处放置陷阱,因为他们害怕青蛙。

你能帮助Slavic和Mihai找出使用一个陷阱可以捕捉到的青蛙的最大数量吗?

输入:
第一行输入一个整数t(1≤t≤100)——测试用例的数量。
每个测试用例的描述如下所示。

每个测试用例的第一行是一个整数n(1≤n≤2⋅10^5)——青蛙的数量,也就是Mihai和Slavic能够移动来放置陷阱的距离。
每个测试用例的第二行是n个整数a1,…,an(1≤ai≤10^9)——对应青蛙的跳跃长度。

保证所有测试用例中n的总和不超过2⋅10^5。

输出:
对于每个测试用例,输出一个整数——使用一个陷阱可以捕捉到的青蛙的最大数量。

 思路:

    先把青蛙的跳跃长度挨个输进frog数组,再在判断每一个跳跃长度有无超过n(超过就放弃,因为陷阱最远就到n),接着把小于n的跳跃步数作为下标,ma[frog[i]]++,记录每一种跳法的青蛙有几只(不用map因为这个跳跃步数不会超过数组的存储范围,数组就可以存,用map时间上会慢一点)。

    然后再挨个处理没一个位置上有几只青蛙可以跳到,从1开始,到j*j=i结束,如果i%j=0,在进行分支判断:

    一:如果j*j=i:则num+=ma[j]

    二:除一以外情况:num+=ma[j],num+=ma[i/j]

(我们可以理解为,a*b=i,也就是两个数的乘积为当前位置,因为我们只到j*j=i就结束了,所以有的乘积会大于j,例如:3*9=27,j到5就结束了)

    ans取最大的num,最后再输出ans。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int frog[N],ma[N];
int main(){
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--){
        int n,ans=0,cnt=0;
        cin>>n;
        for(int i=1;i<=n;i++){
            ma[i]=0;
            cin>>frog[i];
        }
        for(int i=1;i<=n;i++) if(frog[i]<=n) ma[frog[i]]++;
        for(int i=1;i<=n;i++){
            int num=0;
            for(int j=1;j*j<=i;j++){
                if(i%j==0){
                    if(j*j==i) num+=ma[j];
                    else num+=ma[j],num+=ma[i/j];
                }
            }
            ans=max(ans,num);
        }
        cout<<ans<<"\n";
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值