编程语言
首页 > 编程语言> > 2019蓝桥杯国赛C++B组填空部分题解

2019蓝桥杯国赛C++B组填空部分题解

作者:互联网

1.

求等差数列,直接暴力破解

#include<iostream>
using namespace::std;
int main()
{
    for(int i=2019;i<10000;i++)
    {
        for(int j=i+1;j<10000;j++)
        {
            if(i*i-2019*2019==j*j-i*i)
            {
                cout << i <<' '<< j<<' '<<i+j<<endl;
            }
        }
    }
    return 0;
}

答案:7020

2.

DP背包问题,因为每一个数我们只能取一个,所以是一个最简单的01背包,只不过这次转移方程不是min或者max而是直接求总数,想加就好了。

#include<iostream>
using namespace::std;
long long num[2020], vis[2020], t=1;
long long f[2020][2020];
int main()
{
    num[0]=0;
    for(int i=2;i<2019;i++)
    {
        if(!vis[i]){
            num[t++] = i;
            for(int j=i*2;j<2019;j+=i)
            vis[j]=1;
        }
    }
    f[0][0]=1;
    for(long long i=1;i<t;i++)
    {
        for(long long j=0;j<=2019;j++)
        {
            if(j>=num[i])
            {
                f[i][j] += f[i-1][j-num[i]]+f[i-1][j];
            }
            else f[i][j]+=f[i-1][j];
        }
    }
    cout << f[t-1][2019];
    return 0;
}

答案:55965365465060

3.找了半天题目都不全,哭了跳过~

4.

既然是在图上的变化,DFS就肯定会用到,但是我写的方法中DFS出来后会有三个情况不可取,分别是 第一种:直接到了(0,0,);第二种:从(0,0)到(0,1)再回到(0,0); 第三种:从(0,0)到(1,0)再回到(0,0)。

#include<iostream>
using namespace::std;
int total;
int dic_x[4]={1,-1,0,0};
int dic_y[4]={0,0,1,-1};
int vis[10][10];
void dfs(int x, int y, int step)
{
    if(step>12) return;
    if(step<=12)
    {
        if(x==0 && y==0) total++;
    }
    for(int i=0;i<4;i++)
    {
        int tempx=x+dic_x[i];
        int tempy=y+dic_y[i];
        if(tempx>=0 && tempx<=7 && tempy>=0 && tempy<=7 && !vis[tempx][tempy])
        {
            vis[tempx][tempy]=1;
            dfs(tempx, tempy, step+1);
            vis[tempx][tempy]=0;
        }
    }
}
int main()
{
    dfs(0, 0, 0);
    cout << total-3;
    return 0;
}

5.

求质因数的个数,一开始看到的时候脑子里只有一句话“暴力出奇迹,打表进国一”,于是直接暴搜,发现也能出来。

#include<iostream>
using namespace::std;
int counts(long long n)
{
    int count=0;
    for(long long i=1;i<n;i++)
    {
        if(n%i==0) count++;
    }
    return count+1;
}
int main()
{
    for(long long i=2;i<=10000000000;i++)
    {
        if(counts(i)==100) {cout << i; break;}
    }
    return 0;
}

但是本着学习的态度还是多想了想,本题应该考察的是唯一分解定理,也就是素因数的概念。改进过后的代码明显运行更快了,(第一种方法至少跑了2分钟!!!)

#include<iostream>
using namespace::std;
int s[1000005],vis[1000005], m=0;
int counts(int n)
{
    int sum=1;
    int temp=0;
    while (n!=1) {
        int a=0;
        while (n && (n%s[temp])==0) {
            n/=s[temp];
            a++;
        }
        temp++;sum*=(a+1);
    }
    return sum;
}
int main()
{
    for(int i=2;i<=100000;i++)
    {
        if(!vis[i])
        {
            s[m++]=i;
            for(int j=i*2;j<=100000;j+=i)
                vis[j]=1;
        }
    }
    for(int i=2;i<=1000000;i++)
    {
        if(counts(i)==100){cout << i; break;}
    }
    return 0;
}

标签:cout,int,题解,++,long,蓝桥,vis,填空,tempx
来源: https://blog.csdn.net/weixin_45935290/article/details/117567217