240
功不唐捐,玉汝于成😡。

计蒜客 2020蓝桥杯模拟赛第一场补题

一:B组蓝桥杯

A:有趣的数字

题意:
1到 1e5 中质数中包含5这个数字的质数个数

#include<bits/stdc++.h>

using namespace std;
bool pf(int n)
{
    for(int i=2;i<=n/i+1;i++)
    {
        if(n%i==0)
            return false;
    }
    int  m=n;
    while(m)
    {
        if(m%10==5)return true;
        m/=10;
    }
    return false;
}
int main ()
{
    int num=0;
    for(int i=3;i<100000;i++)
    {
        if(pf(i))
        {
            cout<<i<<endl;
         num++;
        }
    }
    cout<<num<<endl;
    return 0;
}

答案:3282

B:爬楼梯

题意:每次只能爬1,2,3,4个台阶,一共十个台阶,第五个和第七个台阶不能使用,到达第十个台阶的方法种类数。

#include<iostream>

//简单递推题:就这几个手推就行 代码纯属糊弄
using namespace std;
int f[20];
int main ()
{
    //最多能走四步则第一个台阶有一种情况,第二个台阶有1+第一个台阶的情况,第三个台阶有 1+第一个台阶情况+第二个台阶情况;
    f[0]=0;
    f[1]=1;
    f[2]=2;//1+1
    f[3]=4;//1+2+1
    f[4]=8;//1+2+4+1
    f[5]=0;//1+2+4+1

    for(int i=6;i<=10;i++)
    {
        if(i==7)continue;
        else f[i]=f[i-1]+f[i-2]+f[i-3]+f[i-4];
    }
    cout<<f[10];
    return 0;
}

答案:72

把那个f[4]算成了7 傻狗一个

C:七巧板

题意:

这个图中加五条直线分割成最多多少个区域。

 

 

emmm 我还以为是从一个空的三角形中画直线,那个 规律也很好找,每个直线尽量切割最多个区域即可,因为一条直线只能将一个区域分割成两个。

emm:再重复一遍 不管是空三角形还是里边有填充的三角形 都是计算下一条直线放到哪里能切割最多区域:下下条似乎是++,依次类推

这道题

 

 

 第一条橙色直线 切6个区域,增加六个区域,下一条紫色直线切7个区域,增加7个区域,依次大胆类推

7+6+7+8+9+10=47 √

答案:47

然后我大胆类推  :空三角形 :1+1+2+3+4+5=16 hhhh(*^_^*)

把空三角形看作是一个平面来处理 似乎是这样子:

 转一个不错的博客如下:

直线/折线/圆/三角形划分平面&直线切割球问题大总结(最多能划分多少区域)

 D:苹果

 

题意:balabla cf改的 差不多意思

 从左往右依次拿,尽量导致最后剩余的苹果更接近0,当下只考虑当前的一个达到最小,3个3个拿到最少之后,与后两个拼凑拿,一直到不能再小再往右遍历

#include<bits/stdc++.h>

using namespace std;
int a[(int)1e3];
int main ()
{
    int n;
    cin.tie(0);
    cin>>n;
    for(int i=0;i<n;i++)
    {
       cin>>a[i];
    }
    int num=0;
    for(int i=0;i<n;i++)
    {
        num+=a[i]/3;
        if(a[i]>=3)
            a[i]%=3;
        if(i<=n-3)
        {
            int mi=min(min(a[i],a[i+1]),a[i+2]);
            num+=mi;
            a[i]-=mi;
            a[i+1]-=mi;
            a[i+2]-=mi;
        }
    }
    cout<<num<<endl;
    return 0;
}

 

 

 

 

 答案:62

 

 E:方阵

题意:再n*n的方阵中,当A和B之间的连线上没有点为A和B可以互相见到,问有多少对这样的AheB 洛谷原题

#include<iostream>

using namespace std;
int gcd(int a,int b){return b==0 ?a:gcd(b,a%b);}
long long dist(int a,int b){return a*a+b*b;}
int main ()
{
    long long num=0;
    long long e=1e9+7;
    int  n;
    long k;
    cin>>n>>k;
    k*=k;
    for(int i=1;i<n;i++)
        for(int j=1;j<n;j++)
    {
        if(gcd(i,j)==1&&dist(i,j)<=k)
            num=(num+(n-j)*(n-i)%e)%e;
    }
    num*=2;
    num+=(2*n*(n-1)%e);
    cout<<num<<endl;
    return 0;
}

 

 

 

 

 

 大体这么个意思 至于怎么化简那个式子 去洛谷看看

 

 

 

F:寻找重复项

题意:有一个数列 \{a_n\}{an},a_0=1a0=1,a_{i+1} =(A\times a_i+a_i \mod B)\mod Cai+1=(A×ai+aimodB)modC,请你编程求出这个数列第一次出现重复的项的标号。如果答案超过 20000002000000 输出 "-1"(不加引号)

#include<iostream>
#include<unordered_map>
using namespace std;
unordered_map<long long,int> p;
int main ()
{
    long long  num=1;
    long long A,B,C;
    cin>>A>>B>>C;
    p[1]=1;
    bool f=true;
    for(int i=1;i<=(int)2e6;i++)
    {
        num=(num*A+ num%B)%C;
        //cout<<num<<endl;
        if(p.count(num))
        {
            f=false;
            cout<<i<<endl;
            break;
        }
        else
            p[num]=1;
    }
    if(f)cout<<-1<<endl;

    return 0;
}

考察 unordered_map或者hash_map 标记

C++ 11标准中加入了unordered系列的容器。unordered_map记录元素的hash值,根据hash值判断元素是否相同。map相当于java中的TreeMap,unordered_map相当于HashMap。无论从查找、插入上来说,unordered_map的效率都优于hash_map,更优于map;而空间复杂度方面,hash_map最低,unordered_map次之,map最大。

对于STL里的map容器,count方法与find方法,都可以用来判断一个key是否出现,count统计的是key出现的次数,因此只能为0/1,而find基于迭代器实现,以mp.end()判断是否找到要求的key。

//摘抄:https://www.cnblogs.com/zzyoucan/p/9127660.html

I 最短路

题意:求1到所有点的距离和所有点回到1的距离最小值

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N=20005,M=60005;
LL sum=0;
struct
{
    int x,y;
    LL z;
}a[M];
LL head[N],ver[M],Next[M],edge[M],d[N];
bool v[N];
int n,m,tot;
priority_queue<pair<LL,int>>p;
void add(int x,int y,LL z)
{
    ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
}
void init()
{
    tot=0;
    memset(head,0,sizeof(head));
    memset(ver,0,sizeof(ver));
    memset(Next,0,sizeof(Next));
    memset(edge,0,sizeof(edge));
}

void dijkstra()
{
    memset(d,0x3f,sizeof(d));
    memset(v,0,sizeof(v));
    p.push(make_pair(0,1));
    d[1]=0;
    while(p.size())
    {
        int x=p.top().second;
        p.pop();//找到当前权值最小的x,o(long n),用x进行更新
        if(v[x])continue;
        v[x]=1;
        for(int i=head[x];i;i=Next[i])
        {
            LL y=ver[i],z=edge[i];
            if(d[y]>d[x]+z)
            {
                d[y]=d[x]+z;
                p.push(make_pair(-d[y],y));
            }
        }
    }
}

int main ()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        init();
      cin>>n>>m;
      for(int i=0;i<m;i++)
      {
          cin>>a[i].x>>a[i].y>>a[i].z;
          add(a[i].x,a[i].y,a[i].z);
      }
      dijkstra();
    for(int i=1;i<=n;i++)
       sum+=d[i];
    init();
    for(int i=0;i<m;i++)
    {
        add(a[i].y,a[i].x,a[i].z);
    }
    dijkstra();
    for(int i=1;i<=n;i++)
        sum+=d[i];
    cout<<sum<<endl;
    sum=0;
    }
    return 0;
}

从1开始跑一次单源最短路,求得1到所有点的权值。

重新建立邻接表,将所有有向路径反向,再跑一次单源最短路,这样求出的1到所有点的最短路就等效于所有点到1的最短路。

结构体储存路径 为了第二次跑最短路

邻接表储存  小根堆优化dijkstra

或者用spfa跑两遍

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N=20005,M=60005;
LL sum=0;
struct
{
    int x,y;
    LL z;
}a[M];
LL head[N],ver[M],Next[M],edge[M],d[N];
bool v[N];
int n,m,tot;
queue<int>p;
void add(int x,int y,LL z)
{
    ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
}
void init()
{
    tot=0;
    memset(head,0,sizeof(head));
    memset(ver,0,sizeof(ver));
    memset(Next,0,sizeof(Next));
    memset(edge,0,sizeof(edge));
}

void spafa()
{
    memset(d,0x3f,sizeof(d));
    memset(v,0,sizeof(v));
    d[1]=0;
    p.push(1);
    while(p.size())
    {
        int x=p.front();
        p.pop();
        v[x]=0;
        for(int i=head[x];i;i=Next[i])
        {
            LL y=ver[i],z=edge[i];
            if(d[y]>d[x]+z)
            {
                d[y]=d[x]+z;
                if(!v[y])p.push(y);
            }
        }
    }
}

int main ()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        init();
      cin>>n>>m;
      for(int i=0;i<m;i++)
      {
          cin>>a[i].x>>a[i].y>>a[i].z;
          add(a[i].x,a[i].y,a[i].z);
      }
      spafa();
    for(int i=1;i<=n;i++)
       sum+=d[i];
    init();
    for(int i=0;i<m;i++)
    {
        add(a[i].y,a[i].x,a[i].z);
    }
   spafa();
    for(int i=1;i<=n;i++)
        sum+=d[i];
    cout<<sum<<endl;
    sum=0;
    }
    return 0;
}

区别不大:(spfa没使用小根堆优化)

 

 上边是spfa 下边是 dijkstra

posted @ 2020-01-18 22:06  BigXun  阅读(709)  评论(1编辑  收藏  举报