博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CCF NOI1154 大整数开方
阅读量:6182 次
发布时间:2019-06-21

本文共 11612 字,大约阅读时间需要 38 分钟。

问题链接


时间限制: 1000 ms  空间限制: 262144 KB

题目描述 

  输入一个正整数n(1<=n<=10^100),输出n的平方根的整数部分。

输入

  正整数n。

输出

  n的平方根的整数部分。

样例输入

10

样例输出

3

数据范围限制

  1<=n<=10^100


问题分析

  这个大整数开方问题需要两样东西,一是大数计算类(找到一个可以用的),二是整数开方算法。这两者一结合,问题就解决了。

程序说明

  这里给出来整数开方算法程序,可以根据这个程序实现大数的开方计算。

  有了大数计算类,实际需要编写的代码就很少了。

要点详解

  • 算法很重要


参考链接

 

关键代码,计算整数开方算法:

// 计算整数开方函数  long sqrt(long n)  {      long a, b, m;      a = 1;      b = n;      for(;;) {          m = (a + b) / 2;          if (m == a || m == b)              return m;          if (m * m > n)              b = m;          else              a = m;      }  }
100分通过的C++程序:

#include 
#include
#include
#include
using namespace std;/* * @author panks * Big Integer library in C++, single file implementation. */#define MAX 10000 // for stringsusing 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 stringprivate: 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
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
BigInteger::divide(string n, long long den) { long long rem = 0; string result; result.resize(MAX); for(int indx=0, len = n.length(); indx
> 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;}// 计算整数开方函数void sqrt(string& n){ BigInteger a=1, b(n), m; for(;;) { m = a + b; m = m / 2; if (m == a || m == b) { cout << m.getNumber() << endl; break; } if (m * m > n) b = m; else a = m; }}int main(){ string s; cin >> s; sqrt(s); return 0;}

转载于:https://www.cnblogs.com/tigerisland/p/7563798.html

你可能感兴趣的文章
利用R语言实现支持向量机(SVM)数据挖掘案例
查看>>
Bash shell脚本的语法结构
查看>>
linux sftp相关命令
查看>>
Like 关键字对时间模糊查询
查看>>
STL之容器共性
查看>>
金笛JDMail邮件系统从源头上为企业铸造防lj邮件墙--3
查看>>
ArcGis for Javascript 的使用注意点
查看>>
FileWriter不能写utf-8的原因及解决
查看>>
IOCP (关于WSASend,WSARecv调用)
查看>>
MOOON-scheduler核心设计图(初稿)
查看>>
网站开发的流程
查看>>
Apache Common-pool2对象池浅析
查看>>
Microsoft Hyper-V Server 2008 R2和SCVMM2012部署XenDesktop 5.6桌面虚拟化系列之二准备虚拟桌面模板...
查看>>
我的友情链接
查看>>
改变虚拟机MAC地址
查看>>
solr教程
查看>>
我的友情链接
查看>>
钱旺之行:互联网经济的增长点——注意力价值经济
查看>>
hadoop Map-Reduce体系架构(3)
查看>>
android语音朗读功能demo实现
查看>>