2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I

目录

  • A: 求余 (水题)
  • B:双阶乘(模拟)
  • C:格点(模拟/枚举)
  • D:整数分解 (闫式dp/数学)
  • E:城邦(并查集+Kruskal)
  • F:特殊年份(模拟)
  • G:小平方 (模拟)
  • H:完全平方数 (分解质因数)
  • I:负载均衡(小根堆 + 模拟)
  • J.完美序列 待补充..

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第1张图片

第二场难度比第一场低了好多
蓝桥杯题解专栏:专栏链接

A: 求余 (水题)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第2张图片

cout << 2021 % 20 << endl;

答案 : 1

B:双阶乘(模拟)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第3张图片

#include 
using namespace std;
int main () {
    int ans = 1;
    for (int i = 2021; i >= 1; i -= 2) {
        ans = ans * i % 100000;//边乘边取余
    }
    cout << ans;
    return 0;
}

答案: 59375

C:格点(模拟/枚举)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第4张图片

//输出字母三角
#include 
using namespace std;
int main () {
    int ans = 0;
    for (int x = 1; x <= 2021; x ++) {
        for (int y = 1; y <= 2021; y ++) {
            if(x * y <= 2021) {
                ans++;
            }
        }
    }
    cout << ans << endl;
}

答案:15698

D:整数分解 (闫式dp/数学)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第5张图片
试了暴力5个for,跑了好久,放弃!
思路一:计数DP

  • 闫式DP分析法:f[i][j] += f[i - 1][j - 1]

集合划分:取i个数且总和为j的所有集合
属性:COUNT

#include 
using namespace std;
typedef long long LL;//数据太大 要开ll
const int N = 5,M = 2021;
LL dp[N + 1][M + 1];//数组开大一点
int main () {
    for (int i = 1; i <= M; i ++) {
        dp[1][i] = 1;//初始化
    }
    for (int i = 2; i <= N; i++) {//枚举个数
        for (int j = 1; j <= M; j++) {
             for (int k = 1; k <= M; k++) {
                    if (j > k) {//枚举所有的数的和
                        dp[i][j] += dp[i - 1][j - k];
                }
            }
         }
    }
    cout << dp[5][2021] << endl;
    return 0;
}

思路二:数学统计 + 隔板法
2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第6张图片

#include 
using namespace std;
typedef long long LL;//数据太大 要开ll
int main () {
    LL ans = 1;
    for (int i = 2020, j = 4; j >= 1; i --,j --) {
        ans *= i / j;
    }
    cout << ans << endl;
    return 0;
}

答案:691677274345

E:城邦(并查集+Kruskal)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第7张图片

#include 
using namespace std;
const int N = 2030, M = N * N / 2;//边数cn2
int n = 2021, m;
int p[N];//并查集
struct Edge {//边
    int a, b, c; //c权重
        bool operator<(const Edge&t) const {
            return c < t.c;
        }
} e[M];

int find (int x) {
    if(p[x] != x) {
        p[x] = find(p[x]);
        return p[x];
    }
}

int get(int x, int y){  //求俩个点的权值
    int res = 0;
    while (x || y) { //当一个数都不为0的时候
        int a = x % 10, b = y % 10;
        if(a!=b) res +=a+b;
        x /= 10, y /= 10;//去个位
    }
    return res;
}

int main () {
    for (int i = 1; i <= n; i ++) {
        p[i] = i; //初始化
    }
    for (int i = 1; i <= n; i ++) {
        for (int j = i + 1; j <= n; j ++) {
            e[m++] = {i, j, get(i, j)};
        }
    }
    sort(e, e + m);//排序所有的边
    int res = 0;
    for (int i = 0; i < m; i ++) {
        int a = e[i].a, b = e[i].b, c = e[i].c;
        if(find(a) != find(b)) {
            res += c;//加上权值
            p[find(a)] = find(b);//合并集合
        }
    }
    cout << res << endl;
    return 0;
}

F:特殊年份(模拟)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第8张图片

#include
using namespace std;
string s;
bool check(string s)
{
    return s[0] == s[2] && s[3] == s[1] + 1;
}
int main()
{
    int cnt = 0;
    for(int i = 0; i < 5; i ++){
        cin >> s;
        if(check(s)) cnt ++;
    }
    cout << cnt << endl;
    return 0;
}

G:小平方 (模拟)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第9张图片

#include
using namespace std;
int main()
{
    int n;
    cin >> n;
    int ans = 0;
    for(int i = 1; i < n; i++) {
        if (i * i % n * 2 < n) {//不要写i*i/2否则会出现浮点数 坑
            ans ++;
        }
    }
    cout << ans << endl;
    return 0;
}

H:完全平方数 (分解质因数)

2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I_第10张图片

质数&质因数知识点

分解质因数:N=p1a1 * p2a2 * p3a3 * … pnan其中pi均为质数,如果一个数是完全平方数,只要让所有的pi均为偶数次幂,开平方就能得到一个整数。

#include 
using namespace std;
typedef long long LL;
int main() {
	int n;
	cin >> n;
	LL res = 1;
	for (int i = 2; i * i < n; i ++) {
		if(n % i == 0) {
			int s;//记录次方数
			while (n % i ==0) { //继续除 并且记录指数
				n /= i;
				s++;	
            }
            if(s%2) res *= i;//如果s是奇数次幂,我们就乘上i
		} 
	}
    if(n > 1) res *= n;
    cout << res << endl;
    return 0;
}

I:负载均衡(小根堆 + 模拟)

#include 
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 200010;
int n,m;
int s[N];//每台计算机算力
priority_queue<PII,vector<PII>,greater<PII> >q[N];//每台计算机任务
//PII <结束时刻,算力>
//!要小根堆
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++ i)scanf("%d",&s[i]);//!下标从1开始
    while (m -- ){
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        while(q[b].size()&&q[b].top().x<=a){//当堆尾的结束时刻小于当前分配时刻
            s[b] += q[b].top().y;//!恢复算力 +
            q[b].pop();//弹出该任务
        }
        if(s[b]<d)puts("-1");//当前算力无法分配
        else{
            q[b].push({a+c,d});//加入任务
            s[b] -= d;//更新算力
            printf("%d\n",s[b]);//输出算力
        }
    }
    return 0;
}

J.完美序列 待补充…

【问题描述】
一个序列中取出一些元素按照原来的顺序排列成新的序列称为该序列的一
个子序列。子序列的价值为子序列中所有元素的和。
如果一个序列是单调递减的,而且除了第一个数以外的任何一个数都是上
一个数的因数,则称这个序列为一个完美序列。
一个序列中的一个子序列如果是完美序列,则称为该序列的一个完美子序
列。一个序列的最长完美子序列长度,称为该序列的完美长度。
给定正整数 n,1 至 n 的所有排列的完美长度的最大值,称为 n 阶最大完
美长度。
给定正整数 n,请求出 1 至 n 的所有排列中长度正好为 n 阶最大完美长度
的所有完美子序列的价值的和。
【输入格式】
每个评测用例包含多组询问。询问之间彼此独立。
输入的第一行包含一个整数 T,表示询问数。
接下来 T 行,每行包含一个整数 n,表示一个给定的 n。
【输出格式】
输出 T 行,依次对应每组询问的答案。
每行包含一个整数,表示对应的答案除以 1000000007 (即 109 + 7) 的余数。
【样例输入】
5
1
2
3
5
10
【样例输出】
1
3
21
140
2268000
【样例说明】
当 n = 1 时,答案显然是 1。 当 n = 2 时,全排列包括 (1, 2) 和 (2, 1),其中 (2, 1) 拥有最长的完美子序
列,也就是 (2, 1) 本身,2 阶最大完美长度为 2,答案即为 2 + 1。 当 n = 3 时,全排列包括 (1, 2, 3)、(1, 3, 2)、(2, 1, 3)、(2, 3, 1)、(3, 1, 2)、
(3, 2, 1)。其中 (2, 1) 和 (3, 1) 都是最长的完美子序列,3 阶最大完美长度为 2。
序列 (1, 2, 3) 和 (1, 3, 2) 中没有长度为 2 的完美子序列。
序列 (2, 1, 3) 中有完美子序列 (2, 1),价值和为 3。
序列 (2, 3, 1) 中有完美子序列 (2, 1) 和 (3, 1),价值和为 7。
序列 (3, 1, 2) 中有完美子序列 (3, 1),价值和为 4。
序列 (3, 2, 1) 中有完美子序列 (2, 1) 和 (3, 1),价值和为 7。
答案为 3 + 7 + 4 + 7 = 21。
【评测用例规模与约定】
对于 10% 的评测用例,n ≤ 10;
对于 20% 的评测用例,n ≤ 20;
对于 30% 的评测用例,T ≤ 20,n ≤ 1000;
对于 40% 的评测用例,T ≤ 20,n ≤ 105;
对于所有评测用例,1 ≤ T ≤ 105,1 ≤ n ≤ 106。

你可能感兴趣的:(蓝桥杯题解,蓝桥杯,c++,算法)