|
|
|
|
讨论 Discussion |
|
| |
难吗????? |
#include <iostream>
// 注意:<fstream> 是iostream的配套库,用于文件操作,符合仅依赖iostream体系的要求
#include <fstream>
using namespace std;
// 牛顿迭代法实现平方根计算(仅用于非负数)
double mySqrt(double num) {
if (num < 0) return 0;
if (num == 0) return 0;
double guess = num / 2;
// 迭代10次,精度足够满足保留5位小数的需求
for (int i = 0; i < 10; i++) {
guess = (guess + num / guess) / 2;
}
return guess;
}
// 字符数组转整数
int strToInt(char *str, int start, int end) {
int num = 0;
int sign = 1;
int i = start;
if (str[i] == '-') {
sign = -1;
i++;
} else if (str[i] == '+') {
i++;
}
for (; i <= end && str[i] >= '0' && str[i] <= '9'; i++) {
num = num * 10 + (str[i] - '0');
}
return num * sign;
}
// 解析表达式,返回系数 [a, b, c]
void parseExpression(char *expr, int &a, int &b, int &c) {
int len = 0;
// 计算表达式长度
while (expr[len] != '\0') len++;
// 处理开头无符号的情况,先临时拼接一个+号
char temp[256] = {0};
int tempIdx = 0;
if (len > 0 && expr[0] != '+' && expr[0] != '-') {
temp[tempIdx++] = '+';
}
for (int i = 0; i < len; i++) {
temp[tempIdx++] = expr[i];
}
len = tempIdx;
int i = 0;
while (i < len) {
// 提取符号
char sign = temp[i];
i++;
// 提取数字部分
int numStart = i;
while (i < len && temp[i] >= '0' && temp[i] <= '9') {
i++;
}
// 处理系数默认为1的情况
int coeff = 1;
if (i > numStart) {
coeff = strToInt(temp, numStart, i - 1);
}
if (sign == '-') {
coeff = -coeff;
}
// 判断项的类型
if (i < len && temp[i] == 'x') {
i++;
if (i < len && temp[i] == '^' && temp[i+1] == '2') {
// 二次项 x^2
a += coeff;
i += 2;
} else {
// 一次项 x
b += coeff;
}
} else {
// 常数项
c += coeff;
}
}
}
// 格式化输出小数到文件流(保留5位小数)
void printDouble(ofstream &fout, double x) {
int integerPart = (int)x;
double decimalPart = x - integerPart;
// 处理负数的小数部分
if (decimalPart < 0) {
decimalPart = -decimalPart;
}
// 四舍五入到5位小数
int decimal5 = (int)(decimalPart * 100000 + 0.5);
fout << integerPart << ".";
// 补零保证5位
if (decimal5 < 10) fout << "0000";
else if (decimal5 < 100) fout << "000";
else if (decimal5 < 1000) fout << "00";
else if (decimal5 < 10000) fout << "0";
fout << decimal5;
}
int main() {
// 打开输入输出文件
ifstream fin("p1646.in");
ofstream fout("p1646.out");
if (!fin.is_open()) { // 容错:检查文件是否打开成功
return 1;
}
char equation[256] = {0};
// 从文件读取一行方程
fin.getline(equation, 256);
// 分割等号左右两边
char left[256] = {0}, right[256] = {0};
int equalPos = -1;
int len = 0;
while (equation[len] != '\0') {
if (equation[len] == '=') {
equalPos = len;
break;
}
len++;
}
// 复制左边
for (int i = 0; i < equalPos; i++) {
left[i] = equation[i];
}
// 复制右边
for (int i = equalPos + 1, j = 0; equation[i] != '\0'; i++, j++) {
right[j] = equation[i];
}
// 初始化系数:ax² + bx + c = 0
int a = 0, b = 0, c = 0;
// 解析左边表达式
parseExpression(left, a, b, c);
// 解析右边表达式(系数取反)
int ra = 0, rb = 0, rc = 0;
parseExpression(right, ra, rb, rc);
a -= ra;
b -= rb;
c -= rc;
// 求解方程并输出到文件
if (a == 0 && b == 0 && c == 0) {
// 无穷多解
fout << 181818181818 << endl;
} else if (a == 0) {
// 一次方程 bx + c = 0
if (b == 0) {
fout << 0 << endl;
} else {
double x = -1.0 * c / b;
fout << 1 << endl;
printDouble(fout, x);
fout << endl;
}
} else {
// 二次方程 ax² + bx + c = 0
double delta = 1.0 * b * b - 4 * a * c;
if (delta < 0) {
fout << 0 << endl;
} else if (delta == 0) {
double x = -1.0 * b / (2 * a);
fout << 1 << endl;
printDouble(fout, x);
fout << endl;
} else {
double sqrtDelta = mySqrt(delta);
double x1 = (-b - sqrtDelta) / (2 * a);
double x2 = (-b + sqrtDelta) / (2 * a);
// 保证小的在前
if (x1 > x2) {
double temp = x1;
x1 = x2;
x2 = temp;
}
fout << 2 << endl;
printDouble(fout, x1);
fout << " ";
printDouble(fout, x2);
fout << endl;
}
}
// 关闭文件流
fin.close();
fout.close();
return 0;
}
( ) |
|
|
|
|
|
|
|
|
|
Flag |
|
题号 |
P1646 |
|
其它 |
通过 |
0人 |
提交 |
1次 |
通过率 |
0% |
难度 |
3 |
|
|
|
|
|
|