2025春季-ACM集训-第一周
摘要
队长:“这俩周的都非常简单”
所以就挑一点有意思的发发啦,不会把代码都挂出来。
B-明明的随机数
\(\qquad\) 排序去重,在输入的时候计个数啥的都能做,也可以直接用两个库函数:
\(\qquad\)\(\qquad\)erase:可以删除 [start, end) 范围内的元素。
\(\qquad\)\(\qquad\)unique:可以将相邻相同的元素移到数组最后,并返回第一个重复元素的迭代器。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; i ++ ) cin >> a[i];
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
cout << a.size() << endl;
for(int i = 0; i < a.size(); i ++ ) cout << a[i] << ' ';
return 0;
}
C-整数去重
\(\qquad\) 这里讲一个 set 容器 insert 时的特殊用法:
\(\qquad\) set 容器的 insert 其实是有返回值的,返回的类型为 pair<iterator, bool>,前者是一个迭代器,指向被插入 set 中的元素或者已经存在于 set 中的拥有相同键值的元素; 而后者则返回是否插入成功,如果在插入前 set 中不含有这个元素,则返回 true 即插入成功,反之则是 false。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
set<int> all;
for(int i = 0; i < n; i ++ ){
int x;
cin >> x;
if(all.insert(x).second) cout << x << ' ';
}
return 0;
}
G-二分法求函数的零点
\(\qquad\) 一个实数域的二分题目,题目已经告诉我们了,函数在 [1.5, 2.4] 上是单调递减的,因此我们只需要判断一下边界与中间值的乘积就可以知道两者是不是在 0 点的同侧了。
#include <bits/stdc++.h>
using namespace std;
double eps = 1e-8;
double check(double m){
return pow(m, 5) - 15*pow(m, 4) + 85*pow(m, 3) - 225*pow(m, 2) + 274*m - 121;
}
int main(){
double l = 1.5, r = 2.4;
while(r-l > eps){
double m = (r+l)/2;
if(check(m)*check(r) > 0) r = m;
else l = m;
}
printf("%.6lf", l);
}
H-高精度加法
\(\qquad\) 高精度运算其实就是模拟竖式计算,先把两个大整数存成数组,再一位位地相加并进位即可。
#include <bits/stdc++.h>
using namespace std;
vector<int> add(vector<int>& A, vector<int>& B){
vector<int> C;
int t = 0;
for(int i = 0; i < max(A.size(), B.size()); i ++ ){
if(i < A.size()) t += A[i];
if(i < B.size()) t += B[i];
C.push_back(t%10);
t /= 10;
}
while(t){
C.push_back(t%10);
t /= 10;
}
return C;
}
int main(){
string a, b;
cin >> a >> b;
vector<int> A, B;
for(int i = a.size()-1; i >= 0; i -- ) A.push_back(a[i]-'0');
for(int i = b.size()-1; i >= 0; i -- ) B.push_back(b[i]-'0');
vector<int> C = add(A, B);
for(int i = C.size()-1; i >= 0; i -- ) cout << C[i];
return 0;
}