点击这里更换您喜欢的皮肤wtboj 首页
请点击这里登入noios   首页 入门 c++讲义 入门教程视频 其他页面 入门视频 站务 公告 | 题库 记录 竞测 测试 闯关 作业 排名 团队 讨论 | 换肤 | 登入 注册  
News >>   新增功能:各团队管理员可以发布本团队作业了 ()

From sina007
难题?水题?
讨论 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&#178; + 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&#178; + 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
提交 讨论 题解
 Copyright wtboj © 2005-2006. www.wutuobang.date Powered by wtboj 关于 联系 帮助
 wtboj Information ---- Total Users : 1367 | Online Users / Processes : 0 / 83 | Processed Time : 859 ms | Server Time : 2026/1/29 13:07:22