2021牛客暑期多校训练营7(题解部分)

地址:2021牛客暑期多校训练营7

H题:xay loves count

题意:

给定一段序列{an},求满足ai*aj=ak的个数(i,j,k可相等),1<=n<=10^6.

思路:

最简单的就是写三重循环,但肯定超时。根据数据就想到了要优化到,nlogn或者n根号n的复杂度。于是就先根据题目所提供的数值也都是1~1e6,所以可以先用桶排来标记一下每个数字出现的次数。最后再遍历一遍看是否满足条件。

但是,最坑人的是ans居然爆Int,淦!这个坑百掉不厌

代码:

#include<iostream>//未优化
using namespace std;
 
int main()
{
    int n,p=0;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            for(int k=0;k<n;k++)
            {
                if(a[i]*a[j]==a[k])
                p++;
            }
        }
    }
    cout<<p;
    return 0;
}
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
 
const int maxn=1e6+5;
int a[maxn];
int num[maxn]={0};
 
int main() {
    int n;
    cin>>n;
    for(int i=0; i<n; i++) {
        cin>>a[i];
        num[a[i]]++;
    }
    sort(a,a+n);
    long long cnt = 0;
    for(int i=0; i<n; i++) {
        for(int j=1; j<(int)sqrt(a[i])+1; j++) {    
            if(a[i]%j==0){
                //cout<<cnt<<"***"<<endl;
                cnt+=num[a[i]/j]*num[j];
                //cout<<a[i]<<" "<<j<<" "<<cnt<<endl;  
                if(a[i]!=j*j){
                    //cout<<a[i]<<" "<<j<<" "<<cnt<<endl;  
                    cnt+=num[a[i]/j]*num[j];
                }              
            }          
        }
    }
    cout<<cnt<<endl;
}
#include<bits/stdc++.h>//附逆十字大佬的代码
using namespace std;
 
const int N=1000005;
int n,x,a[N];
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        scanf("%d",&x),++a[x];
    long long ans=0;
    for (int i=1;i<N;i++)
        for (int j=1;j*i<N;j++)
            ans+=1ll*a[i]*a[j]*a[i*j];
    cout<<ans<<endl;
}

H题:

题意:

xay loves or. He gives you x and s, you need to calculate how many positive integer y satisfy        x or⁡ y= s

思路:

1|1=1,1|0=1,0|1=1,0|0=0.  样例输入2 5

010        对于确定的x,s我们逐位与,通过上面的四种情况可推理出 

101        x,s对应位都是1则y对应位有两种选择,x位上是0则y只有唯一选择,若x为1,s为0是无法实现的。

最后比赛的时候WA了9次,是因为注意题上y是正数,不为零.......................(大无语。。。

代码:

#include<iostream>
using namespace std;
int main() {
    long long x,s;
    //bool X[34],S[34];
    cin>>x>>s;
    long long ans=0;
    int flag=0;
    if(((x&1ll)==1)&&((s&1ll)==1)) {
        ans=2;
    } else if(((x&1ll)==0)&&((s&1ll)==1)) {
        flag=1;
        ans=1;
    } else if(((x&1ll)==0)&&((s&1ll)==0)) {
        ans=1;
    } else if(((x&1ll)==1)&&((s&1ll)==0)) {
        cout<<"0"<<endl;
        return 0;
    }
    x>>=1;
    s>>=1;
    while(x||s) {
        if(((x&1ll)==1)&&((s&1ll)==1)) {
            ans<<=1;
        }
        else if(((x&1ll)==0)&&((s&1ll)==1)){
            flag=1;
        }
        else if(((x&1ll)==1)&&((s&1ll)==0)) {
            ans=0;
            cout<<"0"<<endl;
            return 0;
        }
        //cout<<(x&1ll)<<" "<<(s&1ll)<<endl;
        //cout<<ans<<endl;
        x>>=1;
        s>>=1;
    }
    if(flag==0){
        ans--;
    }
    cout<<ans<<endl;
    return 0;
}

F题:xay loves trees

题意:

思路:

总结:

这一场俩签到题,两人分别开一道,思路都是正确地,可是坑掉少了,计数爆Int,和题上的数值范围的一些坑没有意识到,所以一直卡着,WA了很多次导致排名直冲倒数不是很好。下次需要有debug快速找坑的能力,排名就能upup!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值