2024第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
记录刷题的过程、感悟、题解。
希望能帮到,那些与我一同前行的,来自远方的朋友😉
大纲:
1、握手问题-(解析)-简单组合问题(别人叫她 鸽巢定理)😇,感觉叫高级了
2、小球反弹-(解析)-简单物理问题,不太容易想
3、好数-(解析)-简单运用分支计算
4、R 格式-(解析)-高精度,不是快速幂😉
5、宝石组合-(解析)-lcm推论(gcd、lcm结合)
6、数字接龙-(解析)-DFS(蓝桥专属、每年必有一道)
7、拔河-(解析)-定一端,动一端😎
题目:
1、握手问题
问题描述
小蓝组织了一场算法交流会议,总共有 50 人参加了本次会议。在会议上,大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手 (且仅有一次)。但有 7 个人,这 7 人彼此之间没有进行握手 (但这 7 人与除这 7 人以外的所有人进行了握手)。请问这些人之间一共进行了多少次握手?
注意 A 和 B 握手的同时也意味着 B 和 A 握手了,所以算作是一次握手。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
// 我看大家都叫他鸽巢定理(就是简单的组合问题)
// 其实只需要枚举一下就行了
// 只需要枚举一下就行了
// 举个例子:
// 给所有1~50个人,排一个编号。
// 第50个人,与其他49个人握手,
// 第49个人,与其他48个人握手。(因为第50个人,已经跟他握过了)
// ...
// 第8个人,给其他7个人握手
// 第7个人,就不能跟剩下的6个人握手了(题目:这 7 人彼此之间没有进行握手 )
// 同理,第6个、第5个...
// 因为这个7个人之间,不能相互握手。
#include <iostream>
using namespace std;int main()
{int sum=0;for(int i=7; i<=49; ++i) sum+=i;cout<<sum<<endl;return 0;
}
2、小球反弹
问题描述
有一长方形,长为 343720 单位长度,宽为 2333332 单位长度。在其内部左上角顶点有一小球 (无视其体积),其初速度如图所示且保持运动速率不变,分解到长宽两个方向上的速率之比为 dx:dy=15:17。小球碰到长方形的边框时会发生反弹,每次反弹的入射角与反射角相等,因此小球会改变方向且保持速率不变(如果小球刚好射向角落,则按入射方向原路返回)。从小球出发到其第一次回到左上角顶点这段时间里,小球运动的路程为多少单位长度?答案四舍五入保留两位小数。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个小数,在提交答案时只填写这个小数,填写多余的内容将无法得分。
其实这道题非常简单的啦,画个图,就能解决了。
只要画个图、然后去找他的镜像对称就行。(不断的补充方格就OK喽)
咱们暂定,咱们的速度是1,于是没t秒,运行t个单位。
最后的结果需要乘以2,比较要原路返回🔙。
#include <bits/stdc++.h>
#define ll long longusing namespace std;
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); ll t = 1;ll x=0,y=0; while(1){x=17*t;y=15*t;if(x%233333==0&&y%343720==0) break;else t++;}double len = 2*sqrt((x*x)+(y*y));printf("%.2lf",len);return 0;
}
3、好数
问题描述
一个整数如果按从低位到高位的顺序,奇数位 (个位、百位、万位 ⋯⋯ ) 上的数字是奇数,偶数位 (十位、千位、十万位 ⋯⋯ ) 上的数字是偶数,我们就称之为 “好数”。
给定一个正整数 N,请计算从 1 到 N 一共有多少个好数。
输入格式
一个整数 N。
输出格式
一个整数代表答案。
样例输入 1
24
样例输出 1
7
样例输入 2
2024
样例输出 2
150
样例说明
对于第一个样例,24 以内的好数有 1、3、5、7、9、21、23,一共 7 个。
评测用例规模与约定
对于 10% 的评测用例,1≤N≤100 。
对于 100%的评测用例,1≤N≤10^7 。
其实.....这道题,真的很简单,如果做不出来,只能说,练的少。
其实就是简单的模拟。
当然如果期间你用reverse反转的话,一定会超时。(先把数字转化为字符串,然后将字符串反转一下,奇数位,必须是偶数;偶数位,必须是奇数。)
这是我在网上看的一哥们写的,只能说分支被他玩明白了😇
#include <stdio.h>
int main()
{int n,i;scanf("%d",&n);for(;n>0;n--){for(int m=n;m>0;){if(m%2!=0)m/=10;else break;if(m%2==0)m/=10;else break;if(m==0)i++;}}printf("%d",i);return 0;
}
4、R 格式
问题描述
小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R 格式整数的做法是:
将浮点数乘以 2^n;
四舍五入到最接近的整数。
输入格式
一行输入一个整数 n 和一个浮点数 d,分别表示转换参数,和待转换的浮点数。
输出格式
输出一行表示答案:d 用 R 格式表示出来的值。
样例输入
2 3.14
样例输出
13
样例说明
3.14×22=12.56,四舍五入后为 13。
评测用例规模与约定
对于 50% 的评测用例:1≤n≤10,1≤ 将 d 视为字符串时的长度 ≤15。
对于 100% 的评测用例:1≤n≤1000,1≤ 将 d 视为字符串时的长度 ≤1024;保证 d 是小数,即包含小数点。
哎,被这道题目给骗了😇,第一眼看上去,我还以为是快速幂呢。
其实本题本质上,就是一道高精度题目。
在蓝桥杯中,高精度是一个高频考点,我在最下部,高精度各种计算的模板。 ::传送门::
本题,实际上就是,不断乘以2,当然啦,要用高精度的乘法模版乘。循环n次
当然,要先记录一下数点的位置,然后减去。
#include <bits/stdc++.h>
using namespace std;// 定义两个向量 A 和 B 用于存储高精度数字
vector<int> A, B;// 函数 get 用于实现高精度乘法,将 A 和 B 相乘的结果存回 A
void get() {// 结果向量 C 的大小是 A 和 B 大小之和vector<int> C(A.size() + B.size()); // 逐位相乘并累加到 C 中for(int i = 0; i < A.size(); ++i)for(int j = 0; j < B.size(); ++j)C[i + j] += A[i] * B[j]; // 处理进位int carry = 0;for(int i = 0; i < C.size(); ++i) {carry += C[i];C[i] = carry % 10;carry /= 10; }// 去除前导 0,保留有效数字while(C.size() > 1 && C.back() == 0) C.pop_back(); A = C;
}// 主函数
int main() {int n;string str;// 输入转换参数 n 和待转换的浮点数(以字符串形式输入)cin >> n >> str;// 将字符串反转,方便处理小数部分reverse(str.begin(), str.end()); int pla = 0;// 找到小数点的位置for(int i = 0; i < str.size(); ++i) if(str[i] == '.') {pla = i; break;}// 其实这里能改进的,好在该数只有一个'.',因为 erase 函数的参数如果是字符,它会删除字符串中所有等于该字符的字符。// 而我们只需要删除一个小数点,也可使用 erase 函数的另一个重载版本,传入位置参数// 例如:str.erase(pla, 1);// 将字符串中的数字字符转换为整数存入向量 A,跳过小数点for(int i = 0; i < str.size(); ++i) if(str[i] != '.') A.emplace_back(str[i] - '0'); // 向量 B 初始化为 [2],用于后续的乘法操作B.emplace_back(2);// 执行 n 次乘法操作,即乘以 2 的 n 次方while(n--) get();// 进行四舍五入操作,如果小数点后一位大于等于 5,则进位if(A[pla - 1] >= 5) {int carry = 1;for(int i = pla; i < A.size(); ++i) {carry += A[i];A[i] = carry % 10;carry /= 10;if(carry == 0) break;}if(carry != 0) A.emplace_back(carry);}// 将结果向量 A 反转回正常顺序reverse(A.begin(), A.end());// 去除小数部分,因为题目要求输出整数while(pla--) A.pop_back();// 输出最终结果for(int i : A) cout << i;return 0;
}
5、宝石组合
输入格式
第一行包含一个整数 N 表示宝石个数。
第二行包含 N 个整数表示 N 个宝石的 “闪亮度”。
输出格式
输出一行包含三个整数表示满足条件的三枚宝石的 “闪亮度”。
样例输入
5 1 2 3 4 9
样例输出
1 2 3
评测用例规模与约定
对于 30% 的评测用例:3≤N≤100,1≤Hi≤1000。
对于 60% 的评测用例:3≤N≤2000。
对于 100%的评测用例:3≤N≤10^5,1≤Hi≤10^5 。
像这种题目,要学会做减法,(见好就收)
前提是,你要知道gcd与lcm都是怎么求的,否则一切都是白谈。点击了解 :: 传送门 ::
直接暴力,先拿个30%的分数,“字典序列最小”,也只是听着唬人罢了。😉
首先,我先给出30%的分数,然后在给出100%的解法。
30%
#include <bits/stdc++.h>
using namespace std;
#define int long long
int gcd(int a, int b)
{if (b == 0)return a;return gcd(b, a % b);
}
int lcm(int a, int b)
{return a * b / gcd(a, b);
}
int gcd3(int a, int b, int c)
{return gcd(gcd(a, b), c);
}
int lcm3(int a, int b, int c)
{return lcm(lcm(a, b), c);
}
signed main()
{int n;cin >> n;vector<int> a(n), b(3);for (int i = 0; i < n; i++)cin >> a[i];sort(a.begin(), a.end());int ans = 0;for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){for (int k = j + 1; k < n; k++){int s = a[i] * a[j] * a[k] * lcm3(a[i], a[j], a[k]) / (lcm(a[i], a[j]) * lcm(a[i], a[k]) * lcm(a[j], a[k]));if (s > ans){ans = s;b[0] = a[i];b[1] = a[j];b[2] = a[k];}}}}cout << b[0] << " " << b[1] << " " << b[2];return 0;
}
100%
其实本题最难的,就是把公式给推导出来
就是把推导成gcd(a,b,c)
:: 具体的推导方法 ::
当你把公式推导出来之后,gcd。
首先在输入的时候,推导出gcd最大为多少(根据gcd的性质)
然后不断减减。
假设sum=gcd(a,b,c),说明,a、b、c都是sum的倍数,然后题目就是根据这个推导出来的。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+5;
signed main(){// 既然公式已经推导出来了,那就直接来个大的吧// gcd(a,b,c) 最大数,就是输入的数字int n;cin>>n;vector<int> arr(N,0);int maxN = -1;for(int i=0; i<n; ++i) {int cnt;cin>>cnt; // 输入数据 arr[cnt]++;maxN=max(maxN,cnt);}for(int i=maxN; i>=1; --i){int num=0,cnt[3],flag=0; // flag:有几个数字for(int sum=i; sum<N; sum+=i){if(arr[sum]!=0){for(int k=0; k<arr[sum]&&flag<3; ++k){cnt[flag++]=sum; }}if(flag==3){cout<<cnt[0]<<" "<<cnt[1]<<" "<<cnt[2];return 0;}} }return 0;
}
6、数字接龙
问题描述
小蓝最近迷上了一款名为《数字接龙》的迷宫游戏,游戏在一个大小为 N×N 的格子棋盘上展开,其中每一个格子处都有着一个 0…K−1 之间的整数。游戏规则如下:
从左上角 (0,0) 处出发,目标是到达右下角 (N−1,N−1) 处的格子,每一步可以选择沿着水平/垂直/对角线方向移动到下一个格子。
对于路径经过的棋盘格子,按照经过的格子顺序,上面的数字组成的序列要满足:0,1,2,…,K−1,0,1,2,…,K−1,0,1,2…。
途中需要对棋盘上的每个格子恰好都经过一次(仅一次)。
路径中不可以出现交叉的线路。例如之前有从 (0,0) 移动到 (1,1) ,那么再从 (1,0) 移动到 (0,1) 线路就会交叉。
为了方便表示,我们对可以行进的所有八个方向进行了数字编号,如下图 2 所示;因此行进路径可以用一个包含 0…7 之间的数字字符串表示,如下图 1 是一个迷宫示例,它所对应的答案就是:41255214。
现在请你帮小蓝规划出一条行进路径并将其输出。如果有多条路径,输出字典序最小的那一个;如果不存在任何一条路径,则输出 −1。
输入格式
第一行包含两个整数 N,K 。
接下来输入 N 行,每行 N 个整数表示棋盘格子上的数字。
输出格式
输出一行表示答案。如果存在答案输出路径,否则输出 −1。
样例输入
3 3 0 2 0 1 1 1 2 0 2
样例输出
41255214
样例说明
行进路径如图 1 所示。
评测用例规模与约定
对于 80% 的评测用例:1≤N≤5 。
对于 100% 的评测用例:1≤N≤10,1≤K≤10 。
DFS千篇一律,😇😉,好像都是这个模版耶,稍稍总结一下!嘿嘿(~ ̄▽ ̄)~
#include <bits/stdc++.h>
using namespace std;// 定义棋盘的最大尺寸,这里设置为 15,可根据实际需求调整
const int N = 1e1+5; // 棋盘的边长 n 和数字循环的周期 k
int n, k; // 存储棋盘上每个格子的数字
int arr[N][N]; // 表示八个方向在 x 轴上的偏移量
int fa1[] = {-1, -1, 0, 1, 1, 1, 0, -1};
// 表示八个方向在 y 轴上的偏移量
int fa2[] = {0, 1, 1, 1, 0, -1, -1, -1}; // 用于标记棋盘上的格子是否已经被访问过
bool used[N][N]; // 用于标记两个格子之间的连线是否已经存在,防止路径交叉
bool edge[N][N][N][N]; // 存储当前正在探索的路径
vector<int> res;
// 存储找到的字典序最小的路径
vector<int> t; // 深度优先搜索函数
// cur_x, cur_y 表示当前所在格子的坐标
// cnt 表示当前已经走过的步数(从 1 开始计数)
void dfs(int cur_x, int cur_y, int cnt) {// 如果已经走过了 n * n - 1 步(因为起点已经算走过了)并且到达了右下角if (res.size() == n * n - 1 && cur_x == n - 1 && cur_y == n - 1) {// 如果 t 为空或者当前路径 res 的字典序小于 tif (t.empty() || res < t) {// 更新 t 为当前路径 rest = res;}return;}// 遍历八个方向for (int i = 0; i < 8; ++i) {// 计算下一个格子的坐标int x = cur_x + fa1[i], y = cur_y + fa2[i];// 如果下一个格子超出了棋盘范围,跳过if (x < 0 || x >= n || y < 0 || y >= n) continue; // 如果下一个格子已经被访问过,跳过if (used[x][y]) continue;// 如果是斜向移动(i % 2 == 1)并且当前路径会与已有的路径交叉,跳过if (i % 2 == 1 && (edge[cur_x][y][x][cur_y] || edge[x][cur_y][cur_x][y])) continue; // 如果下一个格子的数字符合当前步数的要求(按照 0 到 k - 1 的循环)if (cnt % k == arr[x][y]) { // 将当前方向加入路径res.push_back(i);// 标记下一个格子为已访问used[x][y] = true;// 标记当前格子和下一个格子之间的连线已存在edge[cur_x][cur_y][x][y] = true;// 递归地继续搜索下一个格子dfs(x, y, cnt + 1);// 回溯,撤销对下一个格子的访问标记used[x][y] = false;// 回溯,撤销当前格子和下一个格子之间的连线标记edge[cur_x][cur_y][x][y] = false;// 回溯,从路径中移除当前方向res.pop_back();} }
}int main() {// 输入棋盘的边长 n 和数字循环的周期 kcin >> n >> k;// 输入棋盘上每个格子的数字for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j) cin >> arr[i][j];// 标记起点为已访问used[0][0] = true;// 从起点 (0, 0) 开始进行深度优先搜索,步数为 1dfs(0, 0, 1);// 如果没有找到符合要求的路径if (t.size() == 0) cout << -1 << endl;else {// 输出字典序最小的路径for (int i : t) cout << i;}return 0;
}
7、拔河
问题描述
小明是学校里的一名老师,他带的班级共有 nn 名同学,第 ii 名同学力量值为 aiai。在闲暇之余,小明决定在班级里组织一场拔河比赛。
为了保证比赛的双方实力尽可能相近,需要在这 nn 名同学中挑选出两个队伍,队伍内的同学编号连续:{al1,al1+1,…,ar1−1,ar1} 和 {al2,al2+1,…,ar2−1,ar2},其中 l1≤r1<l2≤r2。
两个队伍的人数不必相同,但是需要让队伍内的同学们的力量值之和尽可能相近。请计算出力量值之和差距最小的挑选队伍的方式。
输入格式
输入共两行。
第一行为一个正整数 n。
第二行为 n 个正整数 ai。
输出格式
输出共一行,一个非负整数,表示两个队伍力量值之和的最小差距。
样例输入
5 10 9 8 12 14
样例输出
1
样例说明
其中一种最优选择方式:
队伍 1: {a1,a2,a3},队伍 2:{a4,a5},力量值和分别为 10+9+8=27 , 12+14=26,差距为 ∣27−26∣=1 。
评测用例规模与约定
对于 20% 的评测用例,保证 n≤50。
对于 100% 的评测用例,保证 n≤10^3,ai≤10^9 。
大脑模拟一下,就是两个不能重叠的区间,在相互乱动
而,现在,我们要做的,就是定一个区间,动一个区间。
当然,我不知道,会不会有人担心,这样做,会不会漏掉某些区间。
举个例子。
假设共长10。
(以下,看不懂没关系,直接跳过,把代码复制下来问AI😄)
[0,1]区间,此时红线在2这个节点。如下代码遍历时,只能定以2为左端点。
以下代码是不是无法判断[7、8]这个区间?后来是不是会被遗忘点。
完全没必要担心,因为[0,1]会被记录到set中,后续等以7为左边端点时,还能对比。
// 双动态,定一,动一。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N = 1e3+5,Num=0x3f3f3f3f3f3f3f3f;
ll n;
vector<ll> arr(N,0);
vector<ll> sum(N,0);
ll minNum=0x3f3f3f3f3f3f3f3f; // 天哦,原来如此。 int main(){ // 如果定义成这个了,全局该如何避免。 ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n;for(int i=1; i<=n; ++i) {cin>>arr[i];sum[i]=sum[i-1]+arr[i]; } set<ll> s;s.insert(Num); // 模拟插入最大值s.insert(-Num); // 模拟插入最小值 for(int i=2; i<=n; ++i){ // 中间线段 // 存入前缀和for(int j=1; j<=i-1; ++j) s.insert(sum[i-1]-sum[j-1]); // 左边所有区间 // 匹配前缀和 for(int k=i; k<=n; ++k){ll k_sum = sum[k]-sum[i-1];auto it = s.lower_bound(k_sum); // 第一个大于or等于的数字// 目的是找到最相近的数minNum = min(minNum,abs(*it-k_sum));minNum = min(minNum,abs(*(--it)-k_sum)); }} cout<<minNum;return 0;
}
知识点:
1、鸽巢定理(抽屉原理)
基本原理:
常被用于证明存在性证明,和求最坏情况下的解。
- 存在性证明:连最坏情况都不存在解,所以情况也就肯定不存在解。
举例:
其可以解释许多有趣的现象(下文会解释):
- 世界上肯定有两个人头发数量一样多
- 1500人中,至少有5个人的生日相同
- n个人之间握手,一定有两个人握手的次数相同。
- 任意6个人,其中至少有3个人互相不认识,或者互相认识
举例子n个人握手问题,每个人必定会握手0~(n-1)次。所以必定有重复
具体6人问题:把这 6 个人看作 6 个顶点,每两个顶点之间连一条边。
如果两个人互相认识,就把这条边染成红色;如果两个人互相不认识,就把这条边染成蓝色。
那么问题就转化为:在这个由 6 个顶点和它们之间的边构成的图中,一定存在一个同色的三角形(三条边颜色相同的三角形),也就是要么有一个红色三角形(代表三个人互相认识),要么有一个蓝色三角形(代表三个人互相不认识)。
例题:
例题1:hdu1205 吃糖果
(隔板法)
假设N糖果数最多的一种糖果,S是总数-N;
如果:S>=N-1必然有解
S<N-1必然无解, 因为我们把糖果当成隔板了,S<N-1则必然这N个糖果,会存在糖果重叠。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;int K;
LL S, N, x;void solve()
{cin >> K;S = N = 0;for(int i = 1; i <= K; i ++){cin >> x;N = max(N, x);S += x;}S -= N;cout << (S >= N - 1 ? "Yes" : "No") << '\n';
}int main()
{cin.tie(0)->sync_with_stdio(false);cout.tie(0);int T = 1;cin >> T;while (T--){solve();}
}
2、高精度运算
基本概念:
高精度,通常是用来处理大的整数,如超过(int、long long)的整数的加减乘除。
通常是用string字符串或数组来储存这些数,然后模拟手算。
常见类型:
- 高精度加高精度算法
- 高精度减高精度算法
- 高精度乘高精度算法
- 高精度除低精度算法
- 高精度循环加
- 循环高精度乘低精度
高精度+高精度
#include <iostream>
#include <vector>
using namespace std;string add(string str1,string str2){ vector<int> A,B;// 逆序储存,方便计算 for(int i=str1.size()-1; i>=0; --i) A.push_back(str1[i]-'0');for(int i=str2.size()-1; i>=0; --i) B.push_back(str2[i]-'0');// 相加vector<int> c;int carry=0;for(int i=0; i<A.size()||i<B.size()||carry; ++i){if(i<A.size()) carry+=A[i];if(i<B.size()) carry+=B[i];c.push_back(carry%10);carry/=10;} string str="";for(int i=c.size()-1; i>=0; --i) str+=c[i]+'0'; return str;
}int main(){string num1 = "1534";string num2 = "1534";cout<<add(num1, num2);return 0;
}
高精度-高精度
#include <iostream>
#include <vector>
using namespace std;bool cmp(vector<int> A,vector<int> B){ // true-A>=B. false->A<B if(A.size()!=B.size()) return A.size()>B.size(); // 个数不同的情况for(int i=A.size()-1; i>=0; --i){if(A[i]!=B[i]) return A[i]>B[i];}return true;
}
string sub(string str1, string str2){vector<int> A,B;for(int i=str1.size()-1; i>=0; --i) A.push_back(str1[i]-'0');for(int i=str2.size()-1; i>=0; --i) B.push_back(str2[i]-'0');if(!cmp(A,B)) return "-"+sub(str2,str1); // 如果A<B,则交换位置,并加上负号vector<int> C;int borrow=0; // 结尾的数字for(int i=0; i<A.size(); ++i){borrow=A[i]-borrow; // 当前位的数字if(i<B.size()) borrow-=B[i]; // 天呐,这些都是啥玩意 C.push_back((borrow+10)%10); // 借位or不借位,的结果是多少borrow = borrow<0?1:0; } while(C.size()!=1&&C[C.size()-1]==0){C.pop_back();}string str="";for(int i=C.size()-1; i>=0; --i){str+=to_string(C[i]);} return str;
}int main(){string num1 = "1000";string num2 = "1999";cout<<sub(num1,num2);return 0;
}
高精度乘高精度算法
#include <iostream>
#include <vector>
using namespace std;
/*高精度-乘法1、算出最多有多少位2、将每个位置的数字,都乘进他该在的位置,记得用+=(模拟乘法3、设置一个借位的数字carry4、辗转相除,找到他最终的位置5、正常取零
*/
string mul(string str1,string str2){vector<int> A,B;for(int i=str1.size()-1; i>=0; --i) A.push_back(str1[i]-'0');for(int i=str2.size()-1; i>=0; --i) B.push_back(str2[i]-'0');vector<int> C(A.size()+B.size(),0); for(int i=0; i<A.size(); ++i)for(int j=0; j<B.size(); ++j)C[i+j]+=A[i]*B[j]; // !! 这一步,至关重要 int carry = 0;for(int i=0; i<C.size(); ++i){carry=carry+C[i];C[i]=carry%10;carry/=10; }while(C.size()!=1&&C[C.size()-1]==0) C.pop_back();string str="";for(int i=C.size()-1; i>=0; --i) str+=to_string(C[i]);return str;
} int main(){string str1="123";string str2="456";cout<<mul(str1,str2);return 0;
}
高精度除于高精度
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
// 注:写的过程,需要头脑清晰
/*本题需要几个函数除法的实现需要借助(sub减法模拟除法、cmp比较大小 既然是除数了,必然有除数(),也必然存在余数(0or具体的数) 他们都各自用一个vector表示。注意,不要忽略前缀为0的情况用减法模拟除法。
*/bool cmp(vector<int> v1, vector<int> v2){ // 逆序存入,true代表v1>=v2 , false:v1<v2 if(v1.size()!=v2.size()) return v1.size()>v2.size();for(int i=v1.size()-1; i>=0; --i)if(v1[i]!=v2[i]) return v1[i]>v2[i];return true;
}
vector<int> sub(vector<int> v1, vector<int> v2){ // v1>=v2 vector<int> c;int borrow=0; for(int i=0; i<v1.size(); ++i){borrow=v1[i]-borrow; // 借if(i<v2.size()) borrow-=v2[i]; c.push_back((borrow+10)%10);borrow=borrow<0?1:0; }while(c.size()>1&&c.back()==0) c.pop_back();return c;
}string div(string str1, string str2, string& rs){ vector<int> A,B; for(int i=str1.size()-1; i>=0; --i) A.push_back(str1[i]-'0');for(int i=str2.size()-1; i>=0; --i) B.push_back(str2[i]-'0');vector<int> C; // 最后开头可能会产生0 vector<int> cur; // 存放for(int i=str1.size()-1; i>=0; --i){cur.insert(cur.begin(),A[i]); while(cur.size()>1&&cur.back()==0) cur.pop_back(); // 放入 int t=0;while(cmp(cur,B)){cur=sub(cur,B);t++;}C.push_back(t);} // 这一步反转很重要reverse(C.begin(),C.end()); while(C.size()>1&&C.back()==0) C.pop_back();string str=""; for(int i=C.size()-1; i>=0; --i) str+=to_string(C[i]);string r="";for(int i=cur.size()-1; i>=0; --i) r+=to_string(cur[i]);rs=r;return str;
}int main(){// 高精度除数string s1="1234";string s2="23";string remainer; cout<<div(s1,s2,remainer)<<endl;cout<<remainer<<endl; return 0;
}
3、快速幂
简单复习一下,传送门 :: 快速幂 ::
#include <iostream>
using namespace std;
int main(){ // 求3^45 int base=3;int exponent=3;int result=1;while(exponent){if(exponent&1) result*=base;base*=base; exponent>>=1; }cout<<result;
}
4、最大公约数(gcd)与最小公倍数(lca)
最大公约数,就是两个数,共有的最大的因数
lcm是最小公倍数 :: 详细解法 ::
定理:a、b 两个数的最小公倍数(lcm)乘以它们的最大公约数(gcd)等于 a 和 b 本身的乘积。
如:gcd(a,b) * lcm(a,b)=a*b
#include <iostream>
using namespace std;int gcd(int a,int b){ // 最大公约数 return b!=0?gcd(b,a%b):a;
}int main(){ // 我的天呐,简直了int num1=10,num2=8; cout<<gcd(num1,num2)<<endl; // 最大公约数cout<<num1*num2/gcd(num1,num2); // 最小公倍数 return 0;
}
5、gcd与lcm推导

总结:
通过质因数分解和指数分析,我们发现:
- 所有质因数的最小指数相乘,就是三个数的最大公约数(GCD)
- 你在网上列举其他例子也是这样😄,我私下推导过。
借鉴博客:
1、算法学习笔记(25):鸽巢原理(抽屉原理)
2、拔河
3、差分具体用法
相关文章:
2024第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
记录刷题的过程、感悟、题解。 希望能帮到,那些与我一同前行的,来自远方的朋友😉 大纲: 1、握手问题-(解析)-简单组合问题(别人叫她 鸽巢定理)😇,感觉叫高级了…...
Linux系统之wc命令的基本使用
Linux系统之wc命令的基本使用 一、命令简介二、基本语法格式三、核心功能选项四、典型使用案例4.1 创建示例文件4.2 基础统计操作4.3 组合选项使用4.4 管道流处理 五、高级应用技巧4.1 递归统计代码行数4.2 统计CSV文件数据量4.3 监控日志增长速率4.4 字符与字节差异说明 七、命…...
SQL Server 2022 脏读问题排查与思考
总结sqlserver的使用,总是会回想起很多开发过程当中加班努(拼)力(命)的场景,今天,就把之前一个由于数据库脏读到这的OA系统员工请假流程状态不一致问题和解决思路分享一下。 业务场景描述 由于…...
Linux系统时间
1. Linux系统时间 jiffies是linux内核中的一个全局变量,用来记录以内核的节拍时间为单位时间长度的一个数值。 jiffies变量开机时有一个基准值,然后内核每过一个节拍时间jiffies就会加1。 一个时间节拍的时间取决于操作系统的配置,Linux系统一…...
【Windows批处理】命令入门详解
Windows 批处理(Batch Script)是一种用于在 Windows 操作系统上自动执行命令的脚本语言。它基于 Windows 命令提示符(cmd.exe)并使用 .bat 或 .cmd 文件格式。 一、批处理基础 1. 创建批处理文件 批处理脚本本质上是一组按顺序执…...
fpga系列 HDL:ModelSim 条件断点调试 modelsim支持的tcl语言
条件断点调试配置流程: 触发动作用tcl语言描述,modelsim支持的tcl语言见:https://home.engineering.iastate.edu/~zzhang/courses/cpre581-f08/resources/modelsim_quickguide.pdf 运行效果:...
Linux: network: 两台直连的主机业务不通
前提环境,有一个产品的设定是两个主机之间必须是拿网线直连。但是设备管理者可能误将设置配错,不是直连。 最近遇到一个问题,说一个主机发的包,没有到对端,一开始怀疑设定的bond设备的问题,检查了bond的设置状态,发现没有问题,就感觉非常的奇怪。后来就开始怀疑两个主机…...
虚拟地址空间布局架构
一、内存管理架构 1.Linux内核整体架构以及子系统 内存管理子系统架构分为用户空间、内核空间及硬件部分 3 个层面: 用户空间:应用程序使用malloc()申请内存资源,通过free()释放内存资源。内核空间:内核是操作系统的一部分&…...
在VMware下Hadoop分布式集群环境的配置--基于Yarn模式的一个Master节点、两个Slaver(Worker)节点的配置
你遇到的大部分ubuntu中配置hadoop的问题这里都有解决方法!!!(近10000字) 概要 在Docker虚拟容器环境下,进行Hadoop-3.2.2分布式集群环境的配置与安装,完成基于Yarn模式的一个Master节点、两个…...
go day 01
go day 01 配置go环境 install go on D:\huang\lang\go\D:\huang\lang\go\bin\go xxx.go # D:\huang\lang\go\bin 设置到环境变量go go version# 创建任意一个目录,创建三个文件夹 # D:\huang\lang\goProject bin、pkg、src # 创建三个系统环境变量 GOROOT GOPATH GOBIN # GOR…...
(二)RestAPI 毛子(Tags)
文章目录 项目地址一、给Habit添加Tags1.1 创建Tags1. 创建一个新的HabitTags实体2. 设置Habit和Tags的关系3. 设置HabitTag表4. 在HabitConfiguration里配置5. 将表添加到EFCore里6. 迁移数据 1.2 给Habit增加/修改标签1. 创建UpsertHabitTagsDto2. 创建查询HabitWithTagsDto3…...
Elasticsearch:使用机器学习生成筛选器和分类标签
作者:来自 Elastic Andre Luiz 探索使用机器学习模型与传统硬编码方法在搜索体验中自动创建筛选器和分类标签的优缺点 筛选器和分类标签是用来优化搜索结果的机制,帮助用户更快速地找到相关内容或产品。在传统方法中,规则是手动定义的。例如…...
Python接口自动化测试之UnitTest详解
↵ 基本概念 UnitTest单元测试框架是受到JUnit的启发,与其他语言中的主流单元测试框架有着相似的风格。其支持测试自动化,配置共享和关机代码测试。支持将测试样例聚合到测试集中,并将测试与报告框架独立。 它分为四个部分test fixture、Te…...
《概率论与数理统计》期末复习笔记_上
目录 第1章 随机事件与概率 1.1 随机事件 1.2 事件的关系与运算 1.3 概率的定义与性质 1.4 古典概型_重点 1.5 几何概型 1.6 条件概率与乘法公式 1.7 全概率公式与贝叶斯公式_重点 1.8 事件的独立性_重点 1.9 伯努利概型_重难点 第2章 随机变量及其分布 2.1 随机变…...
工程师 - Doxygen介绍
Code Documentation. Automated. Free, open source, cross-platform. Version 1.12.0 is now available! Release date: 7 August 2024 官方网址: Doxygen homepage 文档: Doxygen: Overview Github网址: https://github.com/doxygen/…...
开源且完全没有审核限制的大型语言模型的概述
开源且完全没有审核限制的大型语言模型的概述 关键要点 研究表明,存在多个开源的大型语言模型(LLM)完全没有审核限制,适合开放对话。包括基于 Llama、Mixtral、Phi-2 和 StableLM 的模型,参数范围从 2.78 亿到 4050 亿…...
Qt QTableView QAbstractTableModel实现复选框+代理实现单元格编辑
话不多说,直接看代码 一、Model 1、QTableModel_Test.h #pragma once#include <QAbstractTableModel> #include <QObject> #include <QModelIndex>class QTableModel_Test : public QAbstractTableModel {Q_OBJECT public:QTableModel_Test(Q…...
2025.3.19
1、用vim编辑/etc/hosts文件,将本机和第二个虚拟机的ip地址和主机名写入该文件,然后ping 两个主机的主机名能否ping通; (1)在第一个虚拟机编辑/etc/hosts: 首先使用hostname、hostnamectl、hostname -f指令查看主机名…...
GATT(Generic Attribute Profile)是蓝牙低功耗(Bluetooth Low Energy,简称BLE)协议栈中的一个核心协议
蓝牙的 GATT(Generic Attribute Profile) 是蓝牙低功耗(Bluetooth Low Energy,简称BLE)协议栈中的一个核心协议,用于定义设备如何通过蓝牙进行数据传输和交互。GATT 是基于 ATT(Attribute Proto…...
打造下一代智能体验:交互型 AI 的崛起与实践
在人工智能技术不断飞跃的今天,我们正迎来一个从"一问一答"向"多轮交互、智能反馈"转变的新时代——交互型 AI(Interactive AI)。 什么是交互型 AI? 交互型 AI 指的是具备多轮对话能力、状态记忆、工具调用…...
关于uint8_t、uint16_t、uint32_t、uint64_t的区别与分析
一、类型定义与字节大小 uint8_t、uint16_t、uint32_t、uint64_t 是 C/C 中定义的无符号整数类型,通过 typedef 对基础类型起别名实现。位宽(bit)和字节数严格固定: uint8_t:8 位,占用 1 字节ÿ…...
19685 握手问题
19685 握手问题 ⭐️难度:简单 🌟考点:2024、省赛、数学 📖 📚 package test ;import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);…...
react redux的学习,单个reducer
redux系列文章目录 一 什么redux? redux是一个专门用于做状态管理的JS库(不是react插件库)。它可以用在react, angular, vue等项目中, 但基本与react配合使用。集中式管理react应用中多个组件共享的状 简单来说,就是存储页面的状态值的一个库…...
CCF GESP C++编程 二级认证真题 2025年3月
C 二级 2025 年 03 月 CCF GESP C编程 二级认证真题 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 D C A A D A D A C B C D B C C 1 单选题 第 1 题 2025年春节有两件轰动全球的事件,一个是DeepSeek横空出世,另一个是贺岁片《哪吒2》票房惊人&#…...
Lua函数与表+Lua子文件加载与元表
Lua函数相关示例代码 --脚本型语言,不能先调用,再定义,因为代码是从上往下执行的 --第一种声明函数 function func1()print("这是func1") end--先定义,再调用,没有问题 func1() -------------------------…...
Linux systemd 服务全面详解
一、systemd 是什么? systemd 是 Linux 系统的现代初始化系统(init)和服务管理器,替代传统的 SysVinit 和 Upstart。它不仅是系统启动的“总指挥”,还统一管理服务、日志、设备挂载、定时任务等。 核心作用 服务管理…...
Linux系统调用编程
目录 1.Linux下进程和线程进程线程区别查看进程pid终止进程pid 2.Linux虚拟内存管理与stm32内存映射设计目标与架构差异地址空间管理机制对比内存使用与性能特性 3.Linux系统调用函数fork()wait()exec() 4.树莓派环境下练习创建账号1创建用户账号2.配置用户权限3.查看用户 登录…...
AWS Langfuse AI用Bedrock模型使用完全教程
AWS Langfuse AI使用完全教程 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 AWS Langfuse AI使用完全教程Langfuse是什么?准备工作创建Langfuse账户1.创建LLM应用程序启用Bedrock…...
【Docker项目实战】使用Docker部署MediaCMS内容管理系统
【Docker项目实战】使用Docker部署MediaCMS内容管理系统 前言一、MediaCMS介绍1.1 MediaCMS 简介1.2 主要特点1.3 使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载Med…...
OpenHarmony子系统开发 - DFX(一)
OpenHarmony子系统开发 - DFX(一) 一、DFX概述 简介 在OpenHarmony中,DFX(Design for X)是为了提升质量属性的软件设计,目前包含的内容主要有:DFR(Design for Reliability,可靠性)…...
深入解析:使用Python爬取Bilibili视频
深入解析:使用Python爬取Bilibili视频 引言 Bilibili,作为中国领先的年轻人文化社区,拥有海量的视频资源。对于想要下载Bilibili视频的用户来说,手动下载不仅费时费力,而且效率低下。本文将介绍如何使用Python编写一…...
详解数据结构线性表 c++实现
线性表 线性表是一种非常基础且重要的数据结构,它是具有相同数据类型的 n(n≥0)个数据元素的有限序列。这里的 “有限” 意味着元素的数量是确定的,“序列” 则表示元素之间存在着顺序关系。 顺序表 顺序表是线性表的一种顺序存…...
Prolog语言的网络协议栈
Prolog语言的网络协议栈 引言 网络协议栈是现代计算机网络的重要组成部分,它负责在网络中的各个节点之间以标准化的方式传输数据。在这一体系中,不同层次的协议相互协作,以实现从物理传输到应用层数据处理的功能。Prolog是一种以符号逻辑为…...
音视频基础(音频常用概念)
文章目录 **1. 比特率(Bitrate)****概念****影响****音频比特率****视频比特率** **2. 码率(Bitrate)****3. 帧(Frame)****概念****视频帧****音频帧** **4. 帧长(Frame Length)****…...
洛谷题单3-P5725 【深基4.习8】求三角形-python-流程图重构
题目描述 模仿例题,打印出不同方向的正方形,然后打印三角形矩阵。中间有个空行。 输入格式 输入矩阵的规模,不超过 9 9 9。 输出格式 输出矩形和正方形 输入输出样例 输入 4输出 01020304 05060708 09101112 13141516010203040506 …...
【数据结构】邻接表 vs 邻接矩阵:5大核心优势解析与稀疏图存储优化指南
邻接表法 导读一、邻接矩阵的不足邻接表二、存储结构三、算法评价3.1 时间复杂度3.2 空间复杂度 四、邻接表特点4.1 特点解读特点3特点4特点5 结语 导读 大家好,很高兴又和大家见面啦!!! 图作为一种复杂的数据结构,其…...
编程能力的跃迁时刻:技术革命与认知重构的交响曲
在软件开发领域,从业者常将"一万小时定律"视为能力增长的圭臬,但真正的能力跃迁往往发生在特定技术范式转换的临界点。当开发者首次理解递归算法的本质,当面向对象编程替代过程式思维,当自动化工具链重塑开发流程,这些认知地震时刻往往成为技术生涯的分水岭。 …...
PostIn V1.0.8版本发布,IDEA 插件支持一键扫描上报,让接口定义不再繁琐
PostIn是一款国产开源免费的接口管理工具,包含项目管理、接口调试、接口文档设计、接口数据MOCK等模块,支持常见的HTTP协议、websocket协议等,支持免登陆本地接口调试,同时可以对项目进行灵活的成员权限、消息通知管理等。本周Pos…...
删除Linux服务器上多余的系统启动项,并重装Ubuntu系统
问题描述 2024年6月,Centos团队终止维护Centos7系统,Ubuntu成了我的替换方案。正好有一台闲置的服务器,于是我临危受命给这台服务器重装系统。 经过我一番研究,Ubuntu系统初步安装成功了,但是存在一大堆问题ÿ…...
在亚马逊云科技上使用n8n快速构建个人AI NEWS助理
前言: N8n 是一个强大的工作流自动化工具,它允许您连接不同的应用程序、服务和系统,以创建自动化工作流程,并且采用了开源MIT协议,可以放心使用,他的官方网站也提供了很多的工作流,大家有兴趣的…...
JSON介绍及使用
1.JSON 1.JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据序列化协议,基于文本,完全独立于语言。 JSON由键值对组成,支持以下几种数据类型: 字符串:用双引号括起来的文本。 数…...
AOP 的织入过程是怎样的?
AOP(面向切面编程)的织入(Weaving)是将切面(Aspect)应用到目标对象(Target Object)并创建代理对象(Proxy Object)的过程。这个过程可以发生在不同的阶段&…...
链路聚合配置命令
技术信息 加入捆绑组,加大链路间带宽等 配置命令 华三 静态聚合 将接口加入聚合口后再进行配置 //创建静态链路聚合口1,不启用lacp[SWB]interface Bridge-Aggregation 1 [SWB-Bridge-Aggregation1]port link-type trunk [SWB-Bridge-Aggregation…...
为什么有的深度学习训练,有训练集、验证集、测试集3个划分,有的只是划分训练集和测试集?
在机器学习和深度学习中,数据集的划分方式取决于任务需求、数据量以及模型开发流程的严谨性。 1. 三者划分:训练集、验证集、测试集 目的 训练集(Training Set):用于模型参数的直接训练。验证集(Validati…...
【读书笔记·VLSI电路设计方法解密】问题61:扫描插入的目的是什么
如问题60所述,要构建可测试电路,必须确保电路中每个节点都具有可控性和可观测性。但对于包含时序元件(如触发器、锁存器等存储元件)的电路,若不采取特殊设计则难以实现这两项特性。这是因为时序元件关联节点的逻辑状态不仅取决于当前输入,还受其先前存储状态影响——它们…...
通信数据记录仪-产品概念ID
总结: 1、支持高速CAN、支持容错CAN、支持单线CAN(理解是支持不同的协议,CANFD、CAN2.0和LIN?) 2、 通过上位机设计时间...
【数据分享】2002-2023中国湖泊水位变化数据集(免费获取)
湖泊水位变化是研究水资源动态、生态系统演变和气候变化影响的重要指标。湖泊水位的升降不仅反映了降水、蒸发和入流水量的变化,还与人类活动、气候波动及地质过程密切相关。因此,高精度、长时间序列的湖泊水位数据对于水资源管理、洪水预测以及生态环境…...
SQL注入重新学习
前话 sql注入一般就是构造闭合,在查询语句中构造恶意语句,因为过滤并不严格导致信息泄露, 后台登陆语句:SELECT * FROM admin WHERE Username‘user’ and Password‘pass’ 万能密码:‘or ’1‘ ’1‘ # ; sql常用…...
修改Jupyter Notebook主目录文件夹
1、找到Jupyter Notebook配置文档 在anaconda prompt终端输入以下命令,可以显示配置文档所在位置: jupyter notebook --generate-config2、修改Jupyter Notebook主目录文件夹 用记事本打开文件夹中的jupyter_notebook_config.py文件。 在记事本中使用…...
玩转JSONObject:使用方法详解与Map对比
一、初识JSONObject 什么是JSONObject? JSONObject是Java中处理JSON数据的核心工具类,主流JSON库均提供类似实现: org.json(原生包)com.alibaba.fastjson.JSONObjectnet.sf.json.JSONObject 基础创建姿势 <JAV…...