牛客小白月赛71

A. 猫猫与广告

分析:只需要判断c,d中最小的边大于a,b中最小的边,c,d中最大的边大于a,b中最大的边即可(物尽其用)。

#include
using namespace std;
int a,b,c,d;
int main()
{
    cin>>a>>b>>c>>d;
    if(min(a,b)<=min(c,d)&&max(a,b)<=max(c,d)) puts("YES");
    else puts("NO");
    return 0;
}

B.猫猫与密信

分析:这里采用字符串中的find()函数,找目标字符串下标,目标字符串只有四种,分别是lov、loe、lve、ove,只要找到了输出YES即可。

#include
using namespace std;
int main()
{
    string s;
    cin>>s;
    if(s.find("lov")!=-1||s.find("loe")!=-1||s.find("lve")!=-1||s.find("ove")!=-1)
    {
        puts("YES");
    }
    else 
        puts("NO");
    return 0;
}

C.猫猫与数列

分析:模拟题,根据题述模拟,如果an>M,直接输出,由于数据范围过大我把幂运算转换成了相乘an-1次以防超范围(这里使用log才是最严谨的)。直接上代码。别忘了数据范围开long long。

#include
using namespace std;
long long p,q;
int main()
{
    int cnt=2;
    cin>>p>>q;
    while(1)
    {
        long long res=1;
        for(int i=1;i<=q;i++)
        {
            res*=p;
            if(res>1e18)
            {
                cout<<cnt<<endl;
                return 0;
            }            
        }
        p=q,q=res,cnt++;
    }
    return 0;
}

D.猫猫与主人

分析:这里我从炸鸡块君学到了双指针的操作,建立一个二维平面,将他们按坐标进行排序,固定猫猫顺序枚举。根据他们的位置关系就能枚举出最大的友善值。因为答案要求顺序输出,结构体中还定义了id来存储第几只猫。最后输出即可。

#include
using namespace std;
const int N = 2e5+10;
int n,m;
int res[N];
struct Node
{
    int x,y,id;
    bool operator<(const struct Node &a)const
    {
        if(x!=a.x) return x<a.x;
        return y<a.y;
    }
}c[N],p[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>c[i].x;
    for(int i=1;i<=n;i++) cin>>c[i].y;
    for(int i=1;i<=m;i++) cin>>p[i].y;
    for(int i=1;i<=m;i++) cin>>p[i].x;
    for(int i=1;i<=n;i++) c[i].id=i;
    sort(c+1,c+n+1),sort(p+1,p+m+1);
    int pt=1,my=-1e9;
    for(int i=1;i<=n;i++)
    {
        while(pt<=m&&p[pt].x<=c[i].x)
        {
            my=max(my,p[pt].y);
            pt++;
        }
        if(my>=c[i].y) res[c[i].id]=my;
        else res[c[i].id]=-1;
    }
    for(int i=1;i<=n;i++) cout<<res[i]<<" ";
    puts("");
    return 0;
}

E.猫猫与数学

分析:假设b>a,由gcd(a+c,b+c)=gcd(a-b,a+c)将c放到一边不让两边同时变化,然后sqrt(a-b)<1e7,可枚举a-b的因子,反求出c的值。这里还存在两种特殊情况:如果b-a=1显然输出-1,若b-a=0即b=a,如果两者都为1,为了让他们的gcd不为1,c=1就行了;若两者都不为1,那他们的gcd也不为1,所以c=0。

#include
using namespace std;
long long a,b;
int main()
{
    cin>>a>>b;
    if(a>b) swap(a,b);
    if(b-a==1) puts("-1");
    else if(b-a==0)
    {
        if(a==1) puts("1");
        else puts("0");
    }
    else
    {
        long long c=1e18;
        for(long long i=1;i*i<=(b-a);i++)
        {
            if((b-a)%i==0)
            {
                if(i!=1) c=min(c,i-a%i);
                long long p=(b-a)/i;
                c=min(c,p-a%p);
            }
        }
        cout<<c<<endl;  
    }
    return 0;
}

F.猫猫与宝石

分析:这题的题目根据说明能够理解,但是要从中找出规律有亿点难度,我们还需要了解一些组合数的计算及结论。当i=3时,可以找出他们的系数关系,通过化简可以得到(i+1)/4*(a1+…+ai)。最后得出结论就可以很轻松了。运用了一个快速幂求逆元和前缀和。(由于我不知道如果输入数学公式,这里就没有给出,详细可以看B站炸鸡块君的题解)

#include
using namespace std;
typedef long long ll;
const int N = 2e5+10,mod=998244353;
int n;
ll a[N];
ll qmi(ll a,ll k,int p)
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*a%p;
        a=a*a%p;
        k/=2;
    }
    return res;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) a[i]=(a[i]+a[i-1])%mod;
    for(int i=1;i<=n;i++)
    {
        cout<<(1ll*(1+i)*a[i])%mod*qmi(4,mod-2,mod)%mod<<" ";
    }
    return 0;
}

仅此记录自己的补题心得,如果有误欢迎指出。

你可能感兴趣的:(牛客竞赛,c++,算法)