POJ2389 Bull Math【大数】
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 15040 | Accepted: 7737 |
Description
Read in two positive integers (no more than 40 digits each) and compute their product. Output it as a normal number (with no extra leading zeros).
FJ asks that you do this yourself; don't use a special library function for the multiplication.
Input
Output
Sample Input
11111111111111
1111111111
Sample Output
12345679011110987654321
Source
USACO 2004 November
问题链接:POJ2389 Bull Math。
问题简述:输入两个正整数,它们不超过40位,计算它们的乘积。
问题分析:这是一个大整数计算问题,可以用一个大整数类来实现。
程序说明:编译的时候需要使用G++编译器。求整数绝对值的函数abs()需要用C语言库stdlib.h中的函数,否则会出问题。该问题只用到了乘法运算,为了代码的简洁,可以将不需要的代码删除。这里使用了一个完整的大整数运算类,也可以用于其他地方。
参考链接:B00008 C++实现的大整数计算(一)。
AC的C++语言程序如下:
/* POJ2389 Bull Math */
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
#define MAX 100 // for strings
using namespace std;
class BigInteger {
private:
string number;
bool sign;
public:
BigInteger(); // empty constructor initializes zero
BigInteger(string s); // "string" constructor
BigInteger(string s, bool sin); // "string" constructor
BigInteger(int n); // "int" constructor
void setNumber(string s);
const string& getNumber(); // retrieves the number
void setSign(bool s);
const bool& getSign();
BigInteger absolute(); // returns the absolute value
void operator = (BigInteger b);
bool operator == (BigInteger b);
bool operator != (BigInteger b);
bool operator > (BigInteger b);
bool operator < (BigInteger b);
bool operator >= (BigInteger b);
bool operator <= (BigInteger b);
BigInteger& operator ++(); // prefix
BigInteger operator ++(int); // postfix
BigInteger& operator --(); // prefix
BigInteger operator --(int); // postfix
BigInteger operator + (BigInteger b);
BigInteger operator - (BigInteger b);
BigInteger operator * (BigInteger b);
BigInteger operator / (BigInteger b);
BigInteger operator % (BigInteger b);
BigInteger& operator += (BigInteger b);
BigInteger& operator -= (BigInteger b);
BigInteger& operator *= (BigInteger b);
BigInteger& operator /= (BigInteger b);
BigInteger& operator %= (BigInteger b);
BigInteger& operator [] (int n);
BigInteger operator -(); // unary minus sign
operator string(); // for conversion from BigInteger to string
private:
bool equals(BigInteger n1, BigInteger n2);
bool less(BigInteger n1, BigInteger n2);
bool greater(BigInteger n1, BigInteger n2);
string add(string number1, string number2);
string subtract(string number1, string number2);
string multiply(string n1, string n2);
pair<string, long long> divide(string n, long long den);
string toString(long long n);
long long toInt(string s);
};
//------------------------------------------------------------------------------
BigInteger::BigInteger() { // empty constructor initializes zero
number = "0";
sign = false;
}
BigInteger::BigInteger(string s) { // "string" constructor
if( isdigit(s[0]) ) { // if not signed
setNumber(s);
sign = false; // +ve
} else {
setNumber( s.substr(1) );
sign = (s[0] == '-');
}
}
BigInteger::BigInteger(string s, bool sin) { // "string" constructor
setNumber( s );
setSign( sin );
}
BigInteger::BigInteger(int n) { // "int" constructor
stringstream ss;
string s;
ss << n;
ss >> s;
if( isdigit(s[0]) ) { // if not signed
setNumber( s );
setSign( false ); // +ve
} else {
setNumber( s.substr(1) );
setSign( s[0] == '-' );
}
}
void BigInteger::setNumber(string s) {
number = s;
}
const string& BigInteger::getNumber() { // retrieves the number
return number;
}
void BigInteger::setSign(bool s) {
sign = s;
}
const bool& BigInteger::getSign() {
return sign;
}
BigInteger BigInteger::absolute() {
return BigInteger( getNumber() ); // +ve by default
}
void BigInteger::operator = (BigInteger b) {
setNumber( b.getNumber() );
setSign( b.getSign() );
}
bool BigInteger::operator == (BigInteger b) {
return equals((*this) , b);
}
bool BigInteger::operator != (BigInteger b) {
return ! equals((*this) , b);
}
bool BigInteger::operator > (BigInteger b) {
return greater((*this) , b);
}
bool BigInteger::operator < (BigInteger b) {
return less((*this) , b);
}
bool BigInteger::operator >= (BigInteger b) {
return equals((*this) , b)
|| greater((*this), b);
}
bool BigInteger::operator <= (BigInteger b) {
return equals((*this) , b)
|| less((*this) , b);
}
BigInteger& BigInteger::operator ++() { // prefix
(*this) = (*this) + 1;
return (*this);
}
BigInteger BigInteger::operator ++(int) { // postfix
BigInteger before = (*this);
(*this) = (*this) + 1;
return before;
}
BigInteger& BigInteger::operator --() { // prefix
(*this) = (*this) - 1;
return (*this);
}
BigInteger BigInteger::operator --(int) { // postfix
BigInteger before = (*this);
(*this) = (*this) - 1;
return before;
}
BigInteger BigInteger::operator + (BigInteger b) {
BigInteger addition;
if( getSign() == b.getSign() ) { // both +ve or -ve
addition.setNumber( add(getNumber(), b.getNumber() ) );
addition.setSign( getSign() );
} else { // sign different
if( absolute() > b.absolute() ) {
addition.setNumber( subtract(getNumber(), b.getNumber() ) );
addition.setSign( getSign() );
} else {
addition.setNumber( subtract(b.getNumber(), getNumber() ) );
addition.setSign( b.getSign() );
}
}
if(addition.getNumber() == "0") // avoid (-0) problem
addition.setSign(false);
return addition;
}
BigInteger BigInteger::operator - (BigInteger b) {
b.setSign( ! b.getSign() ); // x - y = x + (-y)
return (*this) + b;
}
BigInteger BigInteger::operator * (BigInteger b) {
BigInteger mul;
mul.setNumber( multiply(getNumber(), b.getNumber() ) );
mul.setSign( getSign() != b.getSign() );
if(mul.getNumber() == "0") // avoid (-0) problem
mul.setSign(false);
return mul;
}
// Warning: Denomerator must be within "long long" size not "BigInteger"
BigInteger BigInteger::operator / (BigInteger b) {
long long den = toInt( b.getNumber() );
BigInteger div;
div.setNumber( divide(getNumber(), den).first );
div.setSign( getSign() != b.getSign() );
if(div.getNumber() == "0") // avoid (-0) problem
div.setSign(false);
return div;
}
// Warning: Denomerator must be within "long long" size not "BigInteger"
BigInteger BigInteger::operator % (BigInteger b) {
long long den = toInt( b.getNumber() );
BigInteger rem;
long long rem_int = divide(number, den).second;
rem.setNumber( toString(rem_int) );
rem.setSign( getSign() != b.getSign() );
if(rem.getNumber() == "0") // avoid (-0) problem
rem.setSign(false);
return rem;
}
BigInteger& BigInteger::operator += (BigInteger b) {
(*this) = (*this) + b;
return (*this);
}
BigInteger& BigInteger::operator -= (BigInteger b) {
(*this) = (*this) - b;
return (*this);
}
BigInteger& BigInteger::operator *= (BigInteger b) {
(*this) = (*this) * b;
return (*this);
}
BigInteger& BigInteger::operator /= (BigInteger b) {
(*this) = (*this) / b;
return (*this);
}
BigInteger& BigInteger::operator %= (BigInteger b) {
(*this) = (*this) % b;
return (*this);
}
BigInteger& BigInteger::operator [] (int n) {
return *(this + (n*sizeof(BigInteger)));
}
BigInteger BigInteger::operator -() { // unary minus sign
return (*this) * -1;
}
BigInteger::operator string() { // for conversion from BigInteger to string
string signedString = ( getSign() ) ? "-" : ""; // if +ve, don't print + sign
signedString += number;
return signedString;
}
bool BigInteger::equals(BigInteger n1, BigInteger n2) {
return n1.getNumber() == n2.getNumber()
&& n1.getSign() == n2.getSign();
}
bool BigInteger::less(BigInteger n1, BigInteger n2) {
bool sign1 = n1.getSign();
bool sign2 = n2.getSign();
if(sign1 && ! sign2) // if n1 is -ve and n2 is +ve
return true;
else if(! sign1 && sign2)
return false;
else if(! sign1) { // both +ve
if(n1.getNumber().length() < n2.getNumber().length() )
return true;
if(n1.getNumber().length() > n2.getNumber().length() )
return false;
return n1.getNumber() < n2.getNumber();
} else { // both -ve
if(n1.getNumber().length() > n2.getNumber().length())
return true;
if(n1.getNumber().length() < n2.getNumber().length())
return false;
return n1.getNumber().compare( n2.getNumber() ) > 0; // greater with -ve sign is LESS
}
}
bool BigInteger::greater(BigInteger n1, BigInteger n2) {
return ! equals(n1, n2) && ! less(n1, n2);
}
string BigInteger::add(string number1, string number2) {
string add = (number1.length() > number2.length()) ? number1 : number2;
char carry = '0';
int differenceInLength = abs( (int) (number1.size() - number2.size()) );
if(number1.size() > number2.size())
number2.insert(0, differenceInLength, '0'); // put zeros from left
else// if(number1.size() < number2.size())
number1.insert(0, differenceInLength, '0');
for(int i=number1.size()-1; i>=0; --i) {
add[i] = ((carry-'0')+(number1[i]-'0')+(number2[i]-'0')) + '0';
if(i != 0) {
if(add[i] > '9') {
add[i] -= 10;
carry = '1';
} else
carry = '0';
}
}
if(add[0] > '9') {
add[0]-= 10;
add.insert(0,1,'1');
}
return add;
}
string BigInteger::subtract(string number1, string number2) {
string sub = (number1.length()>number2.length())? number1 : number2;
int differenceInLength = abs( (int)(number1.size() - number2.size()) );
if(number1.size() > number2.size())
number2.insert(0, differenceInLength, '0');
else
number1.insert(0, differenceInLength, '0');
for(int i=number1.length()-1; i>=0; --i) {
if(number1[i] < number2[i]) {
number1[i] += 10;
number1[i-1]--;
}
sub[i] = ((number1[i]-'0')-(number2[i]-'0')) + '0';
}
while(sub[0]=='0' && sub.length()!=1) // erase leading zeros
sub.erase(0,1);
return sub;
}
string BigInteger::multiply(string n1, string n2) {
if(n1.length() > n2.length())
n1.swap(n2);
string res = "0";
for(int i=n1.length()-1; i>=0; --i) {
string temp = n2;
int currentDigit = n1[i]-'0';
int carry = 0;
for(int j=temp.length()-1; j>=0; --j) {
temp[j] = ((temp[j]-'0') * currentDigit) + carry;
if(temp[j] > 9) {
carry = (temp[j]/10);
temp[j] -= (carry*10);
} else
carry = 0;
temp[j] += '0'; // back to string mood
}
if(carry > 0)
temp.insert(0, 1, (carry+'0'));
temp.append((n1.length()-i-1), '0'); // as like mult by 10, 100, 1000, 10000 and so on
res = add(res, temp); // O(n)
}
while(res[0] == '0' && res.length()!=1) // erase leading zeros
res.erase(0,1);
return res;
}
pair<string, long long> BigInteger::divide(string n, long long den) {
long long rem = 0;
string result;
result.resize(MAX);
for(int indx=0, len = n.length(); indx<len; ++indx) {
rem = (rem * 10) + (n[indx] - '0');
result[indx] = rem / den + '0';
rem %= den;
}
result.resize( n.length() );
while( result[0] == '0' && result.length() != 1)
result.erase(0,1);
if(result.length() == 0)
result = "0";
return make_pair(result, rem);
}
string BigInteger::toString(long long n) {
stringstream ss;
string temp;
ss << n;
ss >> temp;
return temp;
}
long long BigInteger::toInt(string s) {
long long sum = 0;
for(int i=0; i<(int)s.length(); i++)
sum = (sum*10) + (s[i] - '0');
return sum;
}
int main()
{
string a, b;
BigInteger bia, bib, bic;
while(cin >> a >> b) {
bia.setNumber(a);
bib.setNumber(b);
bic = bia * bib;
cout << bic.getNumber() << endl;
}
return 0;
}
转载于:https://www.cnblogs.com/tigerisland/p/7564133.html
POJ2389 Bull Math【大数】的更多相关文章
- POJ2389 Bull Math
/* POJ2389 Bull Math http://poj.org/problem?id=2389 高精度乘法 * */ #include <cstring> #include < ...
- [PKU2389]Bull Math (大数运算)
Description Bulls are so much better at math than the cows. They can multiply huge integers together ...
- Poj OpenJudge 百练 2389 Bull Math
1.Link: http://poj.org/problem?id=2389 http://bailian.openjudge.cn/practice/2389/ 2.Content: Bull Ma ...
- BZOJ1754: [Usaco2005 qua]Bull Math
1754: [Usaco2005 qua]Bull Math Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 374 Solved: 227[Submit ...
- 1754: [Usaco2005 qua]Bull Math
1754: [Usaco2005 qua]Bull Math Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 398 Solved: 242[Submit ...
- POJ 2389 Bull Math(水~Java -大数相乘)
题目链接:http://poj.org/problem?id=2389 题目大意: 大数相乘. 解题思路: java BigInteger类解决 o.0 AC Code: import java.ma ...
- BZOJ 1754: [Usaco2005 qua]Bull Math
Description Bulls are so much better at math than the cows. They can multiply huge integers together ...
- poj 2389.Bull Math 解题报告
题目链接:http://poj.org/problem?id=2389 题目意思:就是大整数乘法. 题目中说每个整数不超过 40 位,是错的!!!要开大点,这里我开到100. 其实大整数乘法还是第一次 ...
- 【BZOJ】1754: [Usaco2005 qua]Bull Math
[算法]高精度乘法 #include<cstdio> #include<algorithm> #include<cstring> using namespace s ...
随机推荐
- MyBatis 学习笔记(1)
MyBatis 的基本构成 SqlSessionFactoryBuilder(构造器):它会根据配置信息或者代码来生成 SqlSessionFactory(工厂接口) SqlSessionFactor ...
- Hadoop安装教程_分布式
Hadoop的分布式安装 hadoop安装伪分布式以后就可以进行启动和停止操作了. 首先需要格式化HDFS分布式文件系统.hadoop namenode -format 然后就可以启动了.start- ...
- Linux网络基础,路由的追踪
一.traceroute traceroute [-46ndFT] [-f<存活数值>] [-g<网关>] [-i(--interface)<device>] [- ...
- C语言 文件操作(四)
1.fprintf int fprintf(FILE *stream, const char *format, ...) stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流 ...
- 24 接口 Interface
/** Java语言的继承是单一继承,一个子类只能有一个父类(一个儿子只能有一个亲爹)* Java语言给我们提供了一种机制,用于处理继承单一的局限性的,接口* 接口:接口是一个比抽象类还抽象的类,接口 ...
- python3(十) iteration
d = {'a': 1, 'b': 2, 'c': 3} for key in d: print(key, end=' ') # a b c dict的存储不是按照list的方式顺序排列,所以,迭代出 ...
- sprigboot 异常 Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].Tomc...
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com ...
- bat中的特殊字符,以及需要在bat中当做字符如何处理
bat中的特殊字符,以及需要在bat中当做字符如何处理 (2014-02-27 21:16:55) 转载▼ 标签: bat 特殊字符 分类: develop bat中的特殊字符,以及需要在bat中当做 ...
- threejs地球之后:动画的控制
上一篇知道如何制作threejs地球之后,就正式coding了,当然还是使用最心爱的Vue.本篇会有一些代码,但是都是十几行的独立片段,相信你不用担心. 布局 在进入本篇主题前,要简单看一下xplan ...
- DLL/OCX文件的注册与数据执行保护DEP
注册/反注册dll或ocx文件时,无论是用regsvr32还是DllRegisterServer/DllUnregisterServer,可能会遇到[内存位置访问无效]的问题: 此时把操作系统的数据执 ...