题目发布于2021年9月23日上午十点。
Problem A
有形如\(ax^3+bx^2+cx+d=0\)这样的一个一元三次方程。给出该方程中各项的系数(\(a,bc,d\)均为实数),并约定该方程存在三个不同实根(根的范围为\([-100,100]\)),且根与根之差的绝对值不小于\(1\)。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后\(2\)位。
输入数据
输入该方程中各项的系数(\(a,b,c,d\)均为浮点数)。
输出数据
由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后\(2\)位。
样例输入
样例输出
题解
二分法的题目。由于该一元三次方程必有三个实根,记\(f(x)=ax^3+bx^2+cx+d\),则\(f'(x)\)必有两个相异实根\(x_1\)与\(x_2\),不妨记\(x_1 <
x_2\),由三次函数的性质及题设可知:三个实根分别在\((-100, x1),(x1, x2),(x2,
100)\)三个区间内。
对三个区间运用二分法即可。注意输出时候要设置格式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream> #include <iomanip> using namespace std; double a, b, c, d; double f(double x) { return (a * x * x * x + b * x * x + c * x + d); } double find_solution(double start, double end) { if (end - start < 0.01) { return (start + end) / 2; } else { double fl = f(start); double fm = f((start + end) / 2.0); if (fl * fm < 0) { return find_solution(start, (start + end) / 2.0 - 0.0001); } else{ return find_solution((start + end) / 2.0 + 0.0001, end); } } } int main() { cin >> a >> b >> c >> d; double seg1 = -100, seg4 = 100; double seg2 = min((-b + sqrt(b * b - 3 * a * c)) / (3 * a), (-b - sqrt(b * b - 3 * a * c)) / (3 * a)); double seg3 = max((-b + sqrt(b * b - 3 * a * c)) / (3 * a), (-b - sqrt(b * b - 3 * a * c)) / (3 * a)); double x1, x2, x3; x1 = find_solution(seg1, seg2); x2 = find_solution(seg2, seg3); x3 = find_solution(seg3, seg4); cout << setiosflags(ios::fixed) << setprecision(2) << x1 << ' ' << x2 << ' ' << x3 << endl; return 0; }
|
Problem B
0-1背包问题的裸题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <iostream> #include <vector> using namespace std; int main() { int N, t; cin >> N >> t; vector<int> w, v; w.push_back(0); v.push_back(0); for(int i = 0; i < N; i++){ int like, cost; cin >> like >> cost; v.push_back(like); w.push_back(cost); } vector<vector<int>> dp(N + 1, vector<int>(t + 1, 0)); for (int i = 1; i <= N; i++) { for (int j = 1; j <= t; j++) { if (j < w[i]) { dp[i][j] = dp[i - 1][j]; } else { dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]); } } } cout << dp[N][t] << endl; return 0; }
|
Problem C
暴力枚举。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <iostream> using namespace std;
const int N = 101;
int arr[N];
bool valid(int a, int b, int c) { return a + b > c && a + c > b && b + c > a; }
int main() { int n; cin >> n; for(int i = 0; i < n; i++) { cin >> arr[i]; } int ans = -1; for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { for(int k = j + 1; k < n; k++) { if(valid(arr[i], arr[j], arr[k])) { ans = max(ans, arr[i] + arr[j] + arr[k]); } } } } cout << ans << endl; return 0; }
|
Problem D
题目描述
在一个被分成\(n \times
n\)个格子的平原上,有一些格子有铁矿,两格铁矿如果相邻那么就认为他们属于同一个矿床,每个矿床都包含一个或更多个铁矿,问一共有几个矿床。两个格子只要有公共边或公共点就算相邻。
输入数据
输入包括\(n+1\)行。
第一行为一个正整数\(n(n \leq
1000)\)。
接下来有\(n\)行,每行有\(n\)个字符,#
表示平原的对应位置有铁矿,*
代表没有。
输出数据
矿床个数。
样例输入
1 2 3 4 5 6 7
| 6 *#*### ###*#* *##*** *#**** ***### ******
|
样例输出
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <iostream> #include <vector> #include <string>
using namespace std;
int totalCount = 0;
const int dx[8] = { 0, 0, -1, 1, 1, -1, 1, -1 }, dy[8] = {1, -1, 0, 0, 1, 1, -1, -1};
void traverseMap(vector<string>& field, int row, int col) { if (row < 0 || col < 0 || row >= field.size() || col >= field.size() || field[row][col] == '*') { return; } field[row][col] = '*'; for (int i = 0; i < 8; i++) { traverseMap(field, row + dx[i], col + dy[i]); } }
void mineCount(vector<string>& field) { for (int i = 0; i < field.size(); i++) { for (int j = 0; j < field.size(); j++) { if (field[i][j] == '#') { totalCount++; traverseMap(field, i, j); } } } }
int main() { int n; cin >> n; if (n > 0) { vector<string> field(n); for (auto& str : field) cin >> str; mineCount(field); } cout << totalCount << endl; return 0; }
|
Problem E
优先队列裸题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <iostream> #include <priority_queue> #include <vector> using namespace std; int main() { int N; cin >> N; priority_queue<int, vector<int>, greater<int>> Q; for (int i = 0; i < N; i++) { int temp; cin >> temp; Q.push(temp); } int ans = 0; for (int i = 0; i < N - 1; i++) { int tempSum = Q.top(); Q.pop(); tempSum += Q.top(); Q.pop(); Q.push(tempSum); ans += tempSum; } cout << ans << endl; return 0; }
|