牛客小白月赛10 A,B,C,D题解

A 勘测:

题目:

传送门A

思路:

找规律,通过找出前几天的建设道路的次数发现为斐波那契额数列,然后求前n项的和即可。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=10000000007;
const int maxn=5*1e6+5;
int n;
ll a[maxn];
ll sum[maxn];
int main()
{
    scanf("%d",&n);
    memset(sum,0,sizeof(sum));
    a[0]=0;sum[0]=0;a[1]=1;a[2]=2;
    sum[1]=1;sum[2]=3;
    for (int i=3;i<=n;i++)
    {
        a[i]=(a[i-1]+a[i-2])%mod;
        sum[i]=(sum[i-1]+a[i])%mod;
    }
    printf("%lld\n",sum[n]%mod);
    return 0;
}

B 数学:

题目:

传送门B

思路:

根据3,5,8,11倍数的特性来进行判定。

如果不知道倍数特性的话可以看看下面这篇博客:

倍数特性

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
string a;
int is[4];
int on[4]={3,5,8,11};
int num=0;
void Judge()
{
    int sum=0,sumo=0,sume=0,sum8=0;
    for (int i=0;i<a.length();i++)
    {
        sum+=a[i]-'0';
        if((i+1)%2)
            sumo+=a[i]-'0';
        else
            sume+=a[i]-'0';
    }
    if(sum%3==0)
        is[0]=1,num++;
    if(a[a.length()-1]=='0'||a[a.length()-1]=='5')
        is[1]=1,num++;
    for (int i=a.length()-1,j=0,k=1;i>=0&&j<3;i--,j++,k*=10)
        sum8=sum8+(a[i]-'0')*k;
    if(sum8%8==0)
        is[2]=1,num++;
    if(abs(sumo-sume)%11==0)
        is[3]=1,num++;
}
int main()
{
    cin>>a;
    memset (is,0,sizeof(is));
    Judge();
    if(num)
    {
        printf("Yes\n");
        for (int i=0;i<4;i++)
        {
            if(is[i])
            {
                printf("%d ",on[i]);
                num--;
            }
        }
        printf("\n");
    }
    else
    {
        printf("No\n");
    }
    return 0;
}

C 约数

题目:

传送门C

思路:

求出a,b的gcd, 然后对gcd进行分解。

代码如下:
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b;
vector<ll>ans;
ll gcd (ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    scanf("%lld%lld",&a,&b);
    ll g=gcd(a,b);
    for (ll i=1;i<=sqrt(g);i++)
    {
        if(g%i==0)
        {
            ans.push_back(i);
            if(i*i!=g)
                ans.push_back(g/i);
        }
    }
    sort(ans.begin(),ans.end());
    for (int i=0;i<ans.size();i++)
    {
        printf("%lld%c",ans[i],i==ans.size()-1?'\n':' ');
    }
    return 0;
}

D 饥饿

题目:

传送门D

思路:

将安全的道路建图, 然后套用迪杰斯特拉算法。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=9223372036854775807;
const int maxn=1e6+5;
int head[maxn];
int n,m,s,t;
ll d[maxn];
struct edge
{
    int to;
    int next;
    ll len;
};
edge e[200005*4];
void addedge (int id,int u,int v,ll len)
{
     e[id].to=v;
     e[id].len=len;
     e[id].next=head[u];
     head[u]=id;
}
void djst()
{
    int vis[maxn];
    memset(vis,0,sizeof(vis));
    for (int i=0;i<=n;i++)
    {
        d[i]=INF;
    }
    d[s]=0;
    while (1)
    {
        ll Max=INF;
        int u=-1;
        for (int i=1;i<=n;i++)
        {
            if(!vis[i]&&Max>d[i])
            {
                Max=d[i];
                u=i;
            }
        }
        if(u==-1)
            break;
        vis[u]=1;
        for (int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            ll len=e[i].len;
            if(!vis[i]&&d[u]+len<d[v])
            {
                d[v]=d[u]+len;
            }
        }
    }
    if(d[t]==INF)
        printf("My gold!!!\n");
    else
        printf("%lld\n",d[t]);
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    memset (head,-1,sizeof(head));
    for (int i=0,id=0;i<m;i++)
    {
        int flag,x,y;
        ll len;
        scanf("%d%d%d%lld",&flag,&x,&y,&len);
        if(flag)
        {
            addedge(id++,x,y,len);
            addedge(id++,y,x,len);
        }
    }
    djst();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41410799/article/details/85255685