蓝桥杯C++大学B组一个月冲刺记录
规则:每日三题
2024/2/27 星期二
由于寒假期间忙着学习语言,为海外留学做准备。所以先刷点简单题热热手
1.斐波纳契数列
打印斐波纳契数列
模拟就行
0 < n < 46
#include<iostream>
#include<cstring>
using namespace std;
int res[100];
void FBI(int n){
if(n > 2){
for(int i = 3;i <= n; ++i){
res[i] = res[i-1] + res[i-2];
}
}
for(int i = 1;i<=n;++i) cout << res[i] << ' ';
return;
}
int main(){
res[1] = 0;
res[2] = 1;
int n;
cin >> n;
FBI(n);
return 0;
}
2.前缀和
前缀和模板罢了
#include<iostream>
using namespace std;
const int Max = 1e5+50;
int n,m;
int res[Max];
int f[Max];
int main(){
cin >> n >> m;
for(int i = 1 ; i<=n ; ++i){
cin >> res[i];
f[i] = f[i-1] + res[i];
}
while(m--){
int l,r;
cin >> l >> r;
cout << f[r] - f[l-1] << '\n';
}
return 0;
}
给定一个按照升序排列的长度为 n 的整数数组,以及 q个查询。
对于每个查询,返回一个元素 k的起始位置和终止位置(位置从 0开始计数)。
如果数组中不存在该元素,则返回 -1 -1。
二分模板,区分两种二分的写法和实际效果!
另外,还需要主要未找到目标数的退出条件。这是写模板笔记的时候没有注意到的地方
还要注意的是数组大小开够没有,第一次交发现数组越界,Segmentation Fault
#include<iostream>
using namespace std;
int n,q;
const int Max = 1e5+50;
int res[Max];
int findleft(int k){
int l = 0;
int r = n-1;
while(l < r){
int mid = (l+r)/2;
if(res[mid] >= k) r = mid;
else l = mid+1;
}
if(res[l] != k) return -1;
else return l;
}
int findright(int k){
int l = 0;
int r = n-1;
while(l < r){
int mid = (l+r+1)/2;
if(res[mid] <= k) l = mid;
else r = mid - 1;
}
if(res[l] != k) return -1;
else return l;
}
int main(){
cin >> n >> q;
for(int i = 0;i < n; ++i){
cin >> res[i];
}
while(q--){
int k;
cin >> k;
int l = findleft(k);
int r = findright(k);
cout << l << ' ' << r << endl;
}
return 0;
}
由于今日和好朋友吃完烤肉酒足饭饱,无所事事所以回来继续做题
4.数的三次方根
题目很简单:给定一个浮点数 n,求它的三次方根。
这个题很考对精度的把握和判断
由于本人菜逼在第一次没有AC,对自我总结了几点
1.考验精度的时候尽量选择都double,而不是float。虽然本题float也能AC
2.在第一次写的时候为了精简计算量,对于l,r初始化条件如下:
double n;
double r = sqrt(n);
double l = sqrt(r);
思考的是,(仅考虑正数的情况下)三次方根大于四次方根,小于二次方根。这样初始化能减少time
但是未知的是sqrt的内部也是二分的情况去求平方根,所以这样初始化会增加很多time,所以第一次交time_limit了
3.由于答案要求结果保留六位小数,所以对于while的条件设定如下
while(r-l > 1e-7){}
计算到第七位才能精准得到前六位的数据
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
float n;
int main(){
cin >> n;
bool flag = true;
if(n < 0){
flag = false;
n = -n;
}
float r = sqrt(n);
float l = sqrt(r);
while(r-l > 1e-7){
float mid = (r+l)/2;
if(mid*mid*mid <= n){
l = mid;
}
else r = mid;
}
if(flag == true) printf("%.6f",l);
else printf("-%.6f",l);
return 0;
}
5.子矩阵的和
easy,注意前缀矩阵如何初始化就可以了
#include<iostream>
using namespace std;
const int Max = 1e3+5;
int p[Max][Max];
int r[Max][Max];
int n,m,q;
int main(){
cin >> n >> m >> q;
for(int i = 1;i <= n; ++i){
for(int j = 1; j <= m ; ++j){
cin >> p[i][j];
r[i][j] = p[i][j];
}
}
for(int i = 1;i <= n; ++i){
for(int j = 1;j <= m; ++j){
r[i][j] += r[i][j-1] + r[i-1][j] - r[i-1][j-1];
}
}
while(q--){
int x1,y1,x2,y2;
cin >> x1 >> y1 >> x2 >> y2;
int res = r[x2][y2] - r[x1 - 1][y2] - r[x2][y1 - 1] + r[x1 - 1][y1 - 1];
printf("%d\n",res);
}
return 0;
}