比赛地址:https://ac.nowcoder.com/acm/contest/8997

A:
按照筛素数的方法,我们可以只判断sqrt(n)里面的数是不是n的因数就可以,再加上n/i的因数,就是答案。
不过,需要特判n是完全数的情况。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n;
    cin>>n;
    long long ans=0;
    for(int i=1;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            ans+=i;
            if(i!=n/i&&i!=1)
            {
                ans+=n/i;
            }
        }
    }
    if(ans>n)
    {
        cout<<"Late"<<endl;
    }
    else if(ans==n)
    {
        cout<<"Pure"<<endl;
    }
    else
    {
        cout<<"Early"<<endl;
    }
    return 0;
}

B:
我们可以把已经知道的移动步骤放入一个vector中,当遇到"Z"且vector不为空时,就弹出末尾的元素,最后再扫一遍vector就可以了。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    vector<int> a;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]!='Z')
        {
            a.push_back(i);
        }
        else if(a.size()>0)
        {
            a.pop_back();
        }
    }
    int x=0,y=0;
    for(int i=0;i<a.size();i++)
    {
        if(s[a[i]]=='W')
        {
            y++;
        }
        else if(s[a[i]]=='A')
        {
            x--;
        }
        else if(s[a[i]]=='S')
        {
            y--;
        }
        else
        {
            x++;
        }
    }
    cout<<x<<" "<<y<<endl;
    return 0;
}

C:
贪心策略:石头和剪刀,剪刀和布,布和石头。
剩下的,尽量平局,加入答案,完成!

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[4],b[4];
    cin>>a[1]>>a[2]>>a[3];
    cin>>b[1]>>b[2]>>b[3];
    long long ans=0;
    int t1,t2;

    t1=a[1],t2=b[2];
    ans+=min(t1,t2)*2;
    a[1]-=min(t1,t2);
    b[2]-=min(t1,t2);

    t1=a[2],t2=b[3];
    ans+=min(t1,t2)*2;
    a[2]-=min(t1,t2);
    b[3]-=min(t1,t2);

    t1=a[3],t2=b[1];
    ans+=min(t1,t2)*2;
    a[3]-=min(t1,t2);
    b[1]-=min(t1,t2);

    int p;
    p=min(a[1],b[1]);
    ans+=p;
    a[1]-=p;
    b[1]-=p;

    p=min(a[2],b[2]);
    ans+=p;
    a[2]-=p;
    b[2]-=p;

    p=min(a[3],b[3]);
    ans+=p;
    a[3]-=p;
    b[3]-=p;

    cout<<ans<<endl;
    return 0;
}

D:
我们先把数组从小到大排序,枚举第一个数,即(i=1......n-1),
再去判断一个区间[l,r],如果两端的数符合条件,那么中间的数一定符合条件。
可以发现r每次是不断减少或者不变的,所以可以保留上次求出的r。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,x,y;
    cin>>n>>x>>y;
    int a[n+1];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    int l=2,r=n;
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        int f1=0,f2=0;
        l=i+1;
        while(l<=n)
        {
            if(a[i]+a[l]>=x&&a[i]+a[l]<=y)
            {
                f1=1;
                break;
            }
            l++;
        }
        while(r>i)
        {
            if(a[i]+a[r]>=x&&a[i]+a[r]<=y)
            {
                f2=1;
                break;
            }
            r--;
        }
        if(f1==1&&f2==1)
        {
            //cout<<l<<" "<<r<<endl;
            ans+=(r-l+1);
        }
        else
        {
            break;
        }
    }
    cout<<ans<<endl;
    return 0;
}

总结:这次比赛比较简单,希望接下来的NOIP有300+