社区讨论
84pts求调
P1480A/B Problem(高精度除法Ⅰ)参与者 4已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @m6ezzzcv
- 此快照首次捕获于
- 2025/01/27 20:01 去年
- 此快照最后确认于
- 2025/11/04 10:14 4 个月前
代码:
CPP#include <bits/stdc++.h>
using namespace std;
namespace things
{
namespace hi_pre
{
/// @brief 无符号高精度类
class uns_hi_pre
{
friend class hi_pre; // 友元类声明,使得其他类可以访问该类私有成员
private:
std::vector<int> data; // 数据,倒序存储
/// @brief 除去无符号高精度数的前导零
/// @param num 一个需要除去前导零的无符号高精度数
/// @return 一个除去前导零后的无符号高精度数
const uns_hi_pre qulin(uns_hi_pre num) const
{
uns_hi_pre t = num;
if (t.data.size() == 0) // 当数字本身就是0时无需除去前导零
return 0;
for (size_t i = t.data.size() - 1; i > 0; --i) // 尝试去除每一位,由于size_t是无符号类型,永远大于等于0,所以不包含最后一位
if (t.data[i] == 0) // 如果是0
t.data.pop_back(); // 去除
else // 否则
break; // 已去除所有前导零,结束循环
if (t.data.back() == 0) // 特判:如果最后一位是0
t.data.pop_back(); // 去除
return t; // 返回已去除前导零后的数字
}
public:
/// @brief 异常类,当一个负数作为无符号高精度数的初值时会抛出此异常
class the_number_is_negative
{
private:
std::string message; // 错误信息
public:
/// @param new_message
the_number_is_negative(const std::string new_message)
{
message = new_message;
}
const std::string what() const
{
return message;
}
};
/// @brief 异常类,当一个用于初始化无符号高精度类或给无符号高精度类赋值的 std::string 字符串不是一个合法数字时会抛出此异常
class the_string_is_not_a_number
{
private:
std::string message; // 错误信息
public:
/// @param new_message
the_string_is_not_a_number(const std::string new_message)
{
message = new_message;
}
const std::string what() const
{
return message;
}
};
uns_hi_pre()
{
*this = 0;
}
uns_hi_pre(const uns_hi_pre &new_data)
{
data = new_data.data;
}
uns_hi_pre &operator=(const uns_hi_pre &new_data)
{
data = new_data.data;
return *this;
}
uns_hi_pre(const unsigned long long num)
{
data.clear();
unsigned long long t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
}
uns_hi_pre &operator=(const unsigned long long num)
{
data.clear();
unsigned long long t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
return *this;
}
uns_hi_pre(const unsigned long num)
{
data.clear();
unsigned long t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
}
uns_hi_pre &operator=(const unsigned long num)
{
data.clear();
unsigned long t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
return *this;
}
uns_hi_pre(const unsigned int num)
{
data.clear();
unsigned int t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
}
uns_hi_pre &operator=(const unsigned int num)
{
data.clear();
unsigned int t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
return *this;
}
uns_hi_pre(const unsigned short num)
{
data.clear();
unsigned short t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
}
uns_hi_pre &operator=(const unsigned short num)
{
data.clear();
unsigned short t = num;
while (t)
{
data.push_back(t % 10);
t /= 10;
}
return *this;
}
uns_hi_pre(const long long num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned long long)(-num));
else // 否则
*this = uns_hi_pre((unsigned long long)(num));
}
uns_hi_pre &operator=(const long long num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned long long)(-num));
else // 否则
*this = uns_hi_pre((unsigned long long)(num));
return *this;
}
uns_hi_pre(const long num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned long)(-num));
else // 否则
*this = uns_hi_pre((unsigned long)(num));
}
uns_hi_pre &operator=(const long num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned long)(-num));
else // 否则
*this = uns_hi_pre((unsigned long)(num));
return *this;
}
uns_hi_pre(const int num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned int)(-num));
else // 否则
*this = uns_hi_pre((unsigned int)(num));
}
uns_hi_pre &operator=(const int num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned int)(-num));
else // 否则
*this = uns_hi_pre((unsigned int)(num));
return *this;
}
uns_hi_pre(const short num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned short)(-num));
else // 否则
*this = uns_hi_pre((unsigned short)(num));
}
uns_hi_pre &operator=(const short num)
{
if (num < 0) // 若数字为负数,则转为正数
*this = uns_hi_pre((unsigned short)(-num));
else // 否则
*this = uns_hi_pre((unsigned short)(num));
return *this;
}
uns_hi_pre(const std::string s)
{
if (s.length() == 0) // 如果是空串
*this = uns_hi_pre(); // 调用默认构造函数初始化
else // 否则
for (int i = s.length() - 1; i >= 0; --i) // 倒序遍历字符串
if (isdigit(s[i])) // 如果是数字
data.push_back(s[i] - '0'); // 转为数字后插入
else // 否则
// 抛出异常
throw(the_string_is_not_a_number(std::string("The std::string \"") + s + std::string("\" is not a number!")));
*this = qulin(*this); // 去除前导零
}
uns_hi_pre &operator=(const std::string s)
{
if (s.length() == 0) // 如果是空串
*this = uns_hi_pre(); // 调用默认构造函数初始化
else // 否则
for (int i = s.length() - 1; i >= 0; --i) // 倒序遍历字符串
if (isdigit(s[i])) // 如果是数字
data.push_back(s[i] - '0'); // 转为数字后插入
else // 否则
// 抛出异常
throw(the_string_is_not_a_number(std::string("The std::string \"") + s + std::string("\" is not a number!")));
*this = qulin(*this); // 去除前导零
return *this;
}
/// @brief 输入函数
/// @param in 输入流(如 cin 等)
/// @param num 要输入的无符号高精度数
friend std::istream &operator>>(std::istream &in, uns_hi_pre &num)
{
std::string s; // 定义字符串
in >> s; // 输入字符串
num = s; // 调用构造函数转数字
return in; // 返回输入流以连续输入
}
/// @brief 输出函数
/// @param in 输出流(如 cout 等)
/// @param num 要输出的无符号高精度数
friend std::ostream &operator<<(std::ostream &out, const uns_hi_pre num)
{
if (num.data.size() == 0) // 如果没有数字
out << 0; // 输出0
else // 否则
for (int i = num.data.size() - 1; i >= 0; --i) // 倒序输出每一位
out << num.data[i]; // 输出第i位
return out; // 返回输出流以连续输出
}
bool operator<(const uns_hi_pre b) const
{
if (this->data.size() != b.data.size()) // 若两数位数不等
{
if (this->data.size() < b.data.size()) // 若前数位数小于后数位数
return true; // 返回true
else // 否则
return false;
} // 返回false
if (this->data.size() == 0) // 若都为0
return false; // 返回false
for (size_t i = this->data.size() - 1; i > 0; --i) // 从高位到低位一次比较每一位,因为无符号整型总是大于等于0,所以特判最后一位
if (this->data[i] != b.data[i]) // 若两数第i位不等
{
if (this->data[i] < b.data[i]) // 若前数第i位小于后数第i位
return true; // 返回true
else // 否则
return false; // 返回false
}
if (this->data[0] != b.data[0]) // 若两数最高位不等
if (this->data[0] < b.data[0]) // 若前数最高位小于后数最高位
return true; // 返回true
else // 否则
return false; // 返回false
else // 否则
return false; // 返回false
}
bool operator>(const uns_hi_pre b) const
{
return b < *this;
}
bool operator==(const uns_hi_pre b) const
{
return !(*this > b) && !(*this < b);
}
bool operator!=(const uns_hi_pre b) const
{
return !(*this == b);
}
bool operator>=(const uns_hi_pre b) const
{
return *this == b || *this > b;
}
bool operator<=(const uns_hi_pre b) const
{
return *this == b || *this < b;
}
const uns_hi_pre operator+(const uns_hi_pre b) const
{
uns_hi_pre ans = 0; // 存储答案的变量
int jw = 0; // 存储进位的变量
for (size_t i = 0; i <= std::max(this->data.size(), b.data.size()); ++i)
{ // 枚举每一位
int da = (i >= this->data.size() ? 0 : this->data[i]); // 当前第一个加数的第i位,若不存在则为0
int db = (i >= b.data.size() ? 0 : b.data[i]); // 当前第二个加数的第i位,若不存在则为0
int d = da + db + jw; // 当前计算结果
ans.data.push_back(d % 10); // 将计算结果加入答案
jw = (d / 10); // 设置进位
}
return qulin(uns_hi_pre(ans)); // 去除前导零并返回
}
uns_hi_pre &operator+=(const uns_hi_pre b)
{
return *this = *this + b;
}
uns_hi_pre &operator++()
{
return *this += 1;
}
const uns_hi_pre operator++(int)
{
const uns_hi_pre t = *this;
++*this;
return t;
}
const uns_hi_pre operator-(const uns_hi_pre b) const
{
uns_hi_pre ans = 0; // 存储答案的变量
int tw = 0; // 存储退位的变量
for (size_t i = 0; i < std::max(this->data.size(), b.data.size()); ++i)
{ // 枚举每一位
int da = (i >= this->data.size() ? 0 : this->data[i]); // 当前第一个加数的第i位,若不存在则为0
int db = (i >= b.data.size() ? 0 : b.data[i]); // 当前第二个加数的第i位,若不存在则为0
int d = da - db - tw; // 当前计算结果
if (d < 0) // 若计算结果小于零
d += 10, tw = 1; // 借1为10
else // 否则
tw = 0; // 重置退位
ans.data.push_back(d); // 将计算结果加入答案
}
if (tw) // 如果仍然有退位,也就是答案是负数
return 0; // 返回0
return qulin(uns_hi_pre(ans)); // 去除前导零并返回
}
uns_hi_pre &operator-=(const uns_hi_pre b)
{
return *this = *this - b;
}
uns_hi_pre &operator--()
{
return *this -= 1;
}
const uns_hi_pre operator--(int)
{
const uns_hi_pre t = *this;
--*this;
return t;
}
const uns_hi_pre operator*(const uns_hi_pre b) const
{
uns_hi_pre ans = 0; // 存储答案的变量
ans.data.resize(this->data.size() + b.data.size()); // 初始化答案位数为两乘数位数之和
for (size_t i = 0; i < this->data.size(); ++i) // 枚举第一个乘数的每一位
{
for (size_t j = 0; j < b.data.size(); ++j) // 枚举第二个乘数的每一位
{
ans.data[i + j] += this->data[i] * b.data[j]; // 答案当前位原数值
ans.data[i + j + 1] += ans.data[i + j] / 10; // 进位累加至下一位
ans.data[i + j] %= 10; // 设置答案当前位实际数值
}
}
return qulin(uns_hi_pre(ans)); // 去除前导零并返回
}
uns_hi_pre &operator*=(const uns_hi_pre b)
{
return *this = *this * b;
}
const uns_hi_pre operator/(const uns_hi_pre b) const
{
uns_hi_pre ans = 0; // 存储答案的变量
uns_hi_pre t = 0; // 存储当前被除数的变量
if (*this == 0)
return 0;
for (size_t i = this->data.size() - 1; i > 0; --i) // 枚举被除数的每一位
{
t.data.insert(t.data.begin(), this->data[i]);
int x = 0; // 存储当前已经尝试次数的变量
while (true)
{
if (t < b) // 如果不能减
break; // 结束循环
t -= b; // 减去
++x; // 增加次数
}
ans.data.insert(ans.data.begin(), x);
}
{
t.data.insert(t.data.begin(), this->data[0]);
int x = 0; // 存储当前已经尝试次数的变量
while (true)
{
if (t < b) // 如果不能减
break; // 结束循环
t -= b; // 减去
++x; // 增加次数
}
ans.data.insert(ans.data.begin(), x);
}
return qulin(uns_hi_pre(ans)); // 去除前导零并返回
}
uns_hi_pre &operator/=(const uns_hi_pre b)
{
return *this = *this / b;
}
const uns_hi_pre operator%(const uns_hi_pre b) const
{
uns_hi_pre ans = 0; // 存储答案的变量
uns_hi_pre t = 0; // 存储当前被除数的变量
if (*this == 0)
return 0;
for (size_t i = this->data.size() - 1; i > 0; --i) // 枚举被除数的每一位
{
t.data.insert(t.data.begin(), this->data[i]);
int x = 0; // 存储当前已经尝试次数的变量
while (true)
{
if (t < b) // 如果不能减
break; // 结束循环
t -= b; // 减去
++x; // 增加次数
}
ans.data.insert(ans.data.begin(), x);
}
{
t.data.insert(t.data.begin(), this->data[0]);
int x = 0; // 存储当前已经尝试次数的变量
while (true)
{
if (t < b) // 如果不能减
break; // 结束循环
t -= b; // 减去
++x; // 增加次数
}
ans.data.insert(ans.data.begin(), x);
}
return qulin(uns_hi_pre(t)); // 去除前导零并返回
}
uns_hi_pre &operator%=(const uns_hi_pre b)
{
return *this = *this % b;
}
// 析构函数
~uns_hi_pre()
{
data = std::vector<int>(); // 清空数据
}
};
}
}
namespace things
{
namespace hi_pre
{
/// @brief 有符号高精度类
class hi_pre
{
private:
uns_hi_pre data;
bool fushu;
hi_pre tiaozhen(const hi_pre x) const
{
hi_pre t = x; // 定义临时变量t=x
t.data += 0; // 使用 +0 去除 t 整数部分的前导零
if (t.data == 0) // 若 t 的整数部分为零
t.fushu = 0; // 将 t 的符号设为正,防止出现 -0 现象
return t; // 返回 t
}
public:
/// @brief 异常类,当一个用于初始化无符号高精度类或给有符号高精度类赋值的 std::string 字符串不是一个合法数字时会抛出此异常
class the_string_is_not_a_number
{
private:
std::string message; // 错误信息
public:
the_string_is_not_a_number(const std::string new_message)
{
message = new_message;
}
const std::string what() const
{
return message;
}
};
/// @brief 类型转换函数,将有符号高精度类转换为无符号高精度类
/// @return 无符号高精度类
/// @warning 由于有符号高精度类中可能存在负数,因此转换为无符号高精度类时,符号位会被丢弃,结果可能不准确。
operator uns_hi_pre()
{
return data;
}
hi_pre()
{
data = uns_hi_pre();
fushu = false;
}
hi_pre(const uns_hi_pre new_data)
{
data = new_data;
fushu = false;
}
hi_pre &operator=(const uns_hi_pre new_data)
{
data = new_data;
fushu = false;
return *this;
}
hi_pre(const hi_pre &new_data)
{
data = new_data.data;
fushu = new_data.fushu;
}
hi_pre &operator=(const hi_pre &new_data)
{
data = new_data.data;
fushu = new_data.fushu;
return *this;
}
hi_pre(const std::string new_data)
{
std::string t = new_data;
if (t[0] == '+' || t[0] == '-') // 若第一位是“+”或“-”
{
if (t[0] == '+') // 若第一位是“+”
fushu = false;
else // 否则
fushu = true;
t.erase(t.begin()); // 删除第一位
}
try // 尝试
{
data = t; // 把删第一位后的字符串赋值给 data
}
catch (const uns_hi_pre::the_string_is_not_a_number &e) // 若出错(剩余部分不是合法数字)
{
throw(the_string_is_not_a_number(std::string("The std::string \"") + new_data + std::string("\" is not a number!"))); // 抛出异常
}
}
hi_pre &operator=(const std::string new_data)
{
std::string t = new_data;
if (t[0] == '+' || t[0] == '-') // 若第一位是“+”或“-”
{
if (t[0] == '+') // 若第一位是“+”
fushu = false;
else // 否则
fushu = true;
t.erase(t.begin()); // 删除第一位
}
try // 尝试
{
data = t; // 把删第一位后的字符串赋值给 data
}
catch (const uns_hi_pre::the_string_is_not_a_number &e) // 若出错(剩余部分不是合法数字)
{
throw(the_string_is_not_a_number(std::string("The std::string \"") + new_data + std::string("\" is not a number!"))); // 抛出异常
}
return *this;
}
hi_pre(const unsigned long long new_data)
{
data = new_data;
}
hi_pre &operator=(const unsigned long long new_data)
{
data = new_data;
return *this;
}
hi_pre(const unsigned long new_data)
{
data = new_data;
}
hi_pre &operator=(const unsigned long new_data)
{
data = new_data;
return *this;
}
hi_pre(const unsigned int new_data)
{
data = new_data;
}
hi_pre &operator=(const unsigned int new_data)
{
data = new_data;
return *this;
}
hi_pre(const unsigned short new_data)
{
data = new_data;
}
hi_pre &operator=(const unsigned short new_data)
{
data = new_data;
return *this;
}
hi_pre(const long long new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > LLONG_MIN)
data = abs(new_data);
else
data = (unsigned long long)LLONG_MAX + 1ULL;
}
hi_pre &operator=(const long long new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > LLONG_MIN)
data = abs(new_data);
else
data = (unsigned long long)LLONG_MAX + 1ULL;
return *this;
}
hi_pre(const long new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > LONG_MIN)
data = abs(new_data);
else
data = (unsigned long)LONG_MAX + 1UL;
}
hi_pre &operator=(const long new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > LONG_MIN)
data = abs(new_data);
else
data = (unsigned long)LONG_MAX + 1UL;
return *this;
}
hi_pre(const int new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > INT_MIN)
data = abs(new_data);
else
data = (unsigned int)INT_MAX + 1U;
}
hi_pre &operator=(const int new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > INT_MIN)
data = abs(new_data);
else
data = (unsigned int)INT_MAX + 1U;
return *this;
}
hi_pre(const short new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > SHRT_MIN)
data = abs(new_data);
else
data = (unsigned short)SHRT_MAX + 1U;
}
hi_pre &operator=(const short new_data)
{
if (new_data < 0)
fushu = true;
else
fushu = false;
if (new_data > SHRT_MIN)
data = abs(new_data);
else
data = (unsigned short)SHRT_MAX + 1U;
return *this;
}
/// @brief 输入函数
/// @param in 输入流(如 cin 等)
/// @param num 要输入的无符号高精度数
friend std::istream &operator>>(std::istream &in, hi_pre &num)
{
std::string s; // 定义字符串
in >> s; // 输入字符串
num = s; // 调用构造函数转数字
num = num.tiaozhen(num); // 调整输入
return in; // 返回输入流以连续输入
}
/// @brief 输出函数
/// @param in 输出流(如 cout 等)
/// @param num 要输出的无符号高精度数
friend std::ostream &operator<<(std::ostream &out, const hi_pre num)
{
hi_pre t = num.tiaozhen(num); // 先调整输出
if (t.fushu) // 如果是负数
out << '-'; // 输出“-”(符号)
out << t.data; // 输出数字部分
return out; // 返回输出流以连续输出
}
bool operator<(const hi_pre b) const
{
if (this->fushu != b.fushu) // 如果两数正负不同
return this->fushu > b.fushu; // 如果自己是负数
else // 否则
return (this->data < b.data) ^ this->fushu; // 比较两数大小,若是负数需要符号取反
}
bool operator>(const hi_pre b) const
{
return b < *this;
}
bool operator==(const hi_pre b) const
{
return !(*this > b || *this < b);
}
bool operator!=(const hi_pre b) const
{
return !(*this == b);
}
bool operator>=(const hi_pre b) const
{
return *this == b || *this > b;
}
bool operator<=(const hi_pre b) const
{
return *this == b || *this < b;
}
const hi_pre operator+(const hi_pre b) const
{
if (b.fushu) // 如果 b 是负数
{
hi_pre t = b; // 定义临时变量 t = b
t.fushu = false; // 将 t 改为它的相反数
return tiaozhen(*this - t); // 返回减去 t 的结果
}
else if (this->fushu) // 否则如果第一个加数是负数
return tiaozhen(b + *this); // 根据加法交换律,交换两数相加
else // 否则,两数都是正数
return tiaozhen(this->data + b.data); // 返回数字部分相加结果
}
hi_pre &operator+=(const hi_pre b)
{
return *this = *this + b;
}
hi_pre &operator++()
{
return *this += 1;
}
const hi_pre operator++(int)
{
const hi_pre t = *this;
++*this;
return t;
}
const hi_pre operator-(const hi_pre b) const
{
if (b.fushu) // 如果 b 是负数
{
hi_pre t = b; // 定义临时变量 t = b
t.fushu = false; // 将 t 改为它的相反数
return tiaozhen(*this + t); // 返回加上 t 的结果
}
else if (this->fushu) // 否则如果第一个减数是负数
{
hi_pre t = *this; // 定义临时变量 t = 自己
t.fushu = !t.fushu; // 将 t 改为它的相反数
t = t + b; // 将 t 改为 t + b
t.fushu = !t.fushu; // 将 t 改为它的相反数
return tiaozhen(t); // 返回 t
}
else if (this->data < b.data) // 否则两数都是负数,如果前数小于后数
{
hi_pre t = b - *this; // 定义临时变量 t = b - 自己
t.fushu = true; // 将 t 改为它的相反数
return tiaozhen(t); // 返回 t
}
else // 否则,两数以及结果都是正数
return tiaozhen(this->data - b.data); // 返回数字部分相减结果
}
hi_pre &operator-=(const hi_pre b)
{
return *this = *this - b;
}
hi_pre &operator--()
{
return *this -= 1;
}
const hi_pre operator--(int)
{
const hi_pre t = *this;
--*this;
return t;
}
const hi_pre operator-() const
{
hi_pre t = *this;
t.fushu = !t.fushu;
return t;
}
const hi_pre operator*(const hi_pre b) const
{
return (hi_pre)0 - b;
}
hi_pre &operator*=(const hi_pre b)
{
return *this = *this * b;
}
const hi_pre operator/(const hi_pre b) const
{
hi_pre t = this->data / b.data;
t.fushu = (this->fushu) ^ (b.fushu);
return t;
}
hi_pre &operator/=(const hi_pre b)
{
return *this = *this / b;
}
const hi_pre operator%(const hi_pre b) const
{
hi_pre t = this->data % b.data;
t.fushu = this->fushu;
return t;
}
hi_pre &operator%=(const hi_pre b)
{
return *this = *this % b;
}
hi_pre operator-()
{
hi_pre t = *this;
t.fushu = !t.fushu;
return tiaozhen(t);
}
};
}
}
things::hi_pre::hi_pre a, b;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> a >> b;
cout << a / b;
return 0;
}
#4
回复
共 9 条回复,欢迎继续交流。
正在加载回复...