问题链接:CCF NOI1154 大整数开方


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

题目描述

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

输入

正整数n。

输出

n的平方根的整数部分。

样例输入

10
样例输出

3

数据范围限制

1<=n<=10^100


问题分析

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

程序说明

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

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

要点详解

  • 算法很重要。

参考链接

B00008 C++实现的大整数计算(一)
Vijos P1786 质因数分解


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

// 计算整数开方函数
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 <iostream>
#include <string>
#include <sstream>
#include <cmath>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 zeroBigInteger(string s); // "string" constructorBigInteger(string s, bool sin); // "string" constructorBigInteger(int n); // "int" constructorvoid setNumber(string s);const string& getNumber(); // retrieves the numbervoid setSign(bool s);const bool& getSign();BigInteger absolute(); // returns the absolute valuevoid 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 ++(); // prefixBigInteger  operator ++(int); // postfixBigInteger& operator --(); // prefixBigInteger  operator --(int); // postfixBigInteger 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 signoperator 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 zeronumber = "0";sign = false;
}BigInteger::BigInteger(string s) { // "string" constructorif( isdigit(s[0]) ) { // if not signedsetNumber(s);sign = false; // +ve} else {setNumber( s.substr(1) );sign = (s[0] == '-');}
}BigInteger::BigInteger(string s, bool sin) { // "string" constructorsetNumber( s );setSign( sin );
}BigInteger::BigInteger(int n) { // "int" constructorstringstream ss;string s;ss << n;ss >> s;if( isdigit(s[0]) ) { // if not signedsetNumber( 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 numberreturn 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) { // postfixBigInteger before = (*this);(*this) = (*this) + 1;return before;
}BigInteger& BigInteger::operator --() { // prefix(*this) = (*this) - 1;return (*this);}BigInteger BigInteger::operator --(int) { // postfixBigInteger before = (*this);(*this) = (*this) - 1;return before;
}BigInteger BigInteger::operator + (BigInteger b) {BigInteger addition;if( getSign() == b.getSign() ) { // both +ve or -veaddition.setNumber( add(getNumber(), b.getNumber() ) );addition.setSign( getSign() );} else { // sign differentif( 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) problemaddition.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) problemmul.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) problemdiv.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) problemrem.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 signreturn (*this) * -1;
}BigInteger::operator string() { // for conversion from BigInteger to stringstring signedString = ( getSign() ) ? "-" : ""; // if +ve, don't print + signsignedString += 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 +vereturn true;else if(! sign1 && sign2)return false;else if(! sign1) { // both +veif(n1.getNumber().length() < n2.getNumber().length() )return true;if(n1.getNumber().length() > n2.getNumber().length() )return false;return n1.getNumber() < n2.getNumber();} else { // both -veif(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 leftelse// 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';} elsecarry = '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');elsenumber1.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 zerossub.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);} elsecarry = 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 onres = add(res, temp); // O(n)}while(res[0] == '0' && res.length()!=1) // erase leading zerosres.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;
}// 计算整数开方函数
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;elsea = m;}
}int main()
{string s;cin >> s;sqrt(s);return 0;
}

CCF NOI1154 大整数开方相关推荐

  1. 信奥中的数学:前缀和与差分、大整数开方技巧

    [算法2-1]前缀和与差分 [算法2-1]前缀和与差分 - 题单 - 洛谷 前缀和与差分 图文并茂 超详细整理(全网最通俗易懂) 前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)_林深不见鹿 的博 ...

  2. 整数平方根:整数开方及大整数开方解决方法

    求整数N的开方,精度在0.001 二分法 若N大于1,则从[1, N]开始,low = 1, high = N, mid = low + (high - low) >> 1开始进行数值逼近 ...

  3. vijos-1447 开关灯泡-大整数开方算法

    描述 一个房间里有n盏灯泡,一开始都是熄着的,有1到n个时刻,每个时刻i,我们会将i的倍数的灯泡改变状态(即原本开着的现将它熄灭,原本熄灭的现将它点亮),问最后有多少盏灯泡是亮着的. 提示 范围:40 ...

  4. java中的开方方法_java 大整数开方模板与常用方法

    BigInteger开方: public static BigInteger Sqrt(BigInteger xx) { BigDecimal x=new BigDecimal(xx); BigDec ...

  5. A1136 | 字符串处理、大整数运算

    题目链接: https://www.patest.cn/contests/pat-a-practise/1136 今天是12月17号.最近这几天都有点不在状态.已经整整一周没有练算法了,自从12.3考 ...

  6. Cryp.1.大整数相乘---分治法

    from:2017 CCF计算机课程改革导教班. 陈道蓄 11 大整数相乘 – 比长乘更快 小学里就教过整数乘的算法.要计算两个正整数a,b的乘积,你用b中每一位依次乘a,并将结果逐行排列,按b的相应 ...

  7. java大整数类减1,自己写Java大整数《1》表示和加减

    自己写Java大整数<一>表示和加减 上周粗略计划自己写Java下的大整数运算. 后来仔细想想其实自己动手写大整数运算有1好2不好.2个不好分别是: 1,肯定没有Java内置的BigInt ...

  8. c语言程序做四则运算还要余数,大整数四则运算 高质量C语言程序.doc

    大整数四则运算 高质量C语言程序 设计题目: 大整数的四则运算 1. 功能简介:编写出实现大整数之间相加,相减,相乘,相除的程序,并输出计算结构. 课程设计要求:采用模块化程序设计 源程序中应有足够的 ...

  9. python整数池_【Python】Python中神奇的小整数对象池和大整数对象池

    小整数对象池 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间. Python 对小整数的定义是 [-5, 256] 这些整数对象是提前建立 ...

最新文章

  1. 2013河北省职称计算机应用能力考试操作题答案,2013河北省职称计算机应用能力考试操作题步骤详解(部分).doc...
  2. 花体英文字帖pdf可打印_考研政治 | 马原24个主观题答题原理!PDF可打印!
  3. SAP UI5 应用开发教程之七 - JSON 模型初探
  4. Java IO: 并发IO
  5. 有一本书,适合零到十年经验的程序员看
  6. mysql-connector-odbc-5.3.12-win32.msi安装步骤
  7. 一些没啥意思的出题想法记录
  8. Winform开发全套31个UI组件开源共享
  9. 手持式自动锁螺丝机怎么操作使用
  10. epub电子书格式转换(E-book Conversion翻译) -- calibre
  11. 隆重推荐:吴闲云 - 三国中的博弈
  12. 树莓派RaspBerryPi上使用3g模块
  13. Python-练习 43. 面向对象的分析和设计基础
  14. mysql查询是第几条记录_MySQL查询第几行到第几行记录
  15. Virtex—5 GTP和Virtex—6 GTX间匹配通信研究及应用
  16. mysql 2038年问题_64位Ubuntu系统的时间戳,2038年问题
  17. 随性随笔_201606
  18. GitLab CI/CD Variables 中文文档
  19. 顺序表实现图书信息管理系统
  20. 中国人民大学与加拿大女王大学金融硕士引领你走出职场困境,勇往直前!

热门文章

  1. esri-leaflet入门教程(5)- 动态绘制图形
  2. Intellij Idea打包jar
  3. java里函数式表达式_java8入门(lambda表达式、函数式接口相关)
  4. 操作系统_图解deepin操作系统安装,体验定制版的国产操作系统
  5. ros先订阅后发布 无法收到消息的解决办法
  6. 判断数据是增量分区全量分区
  7. .net登录界面_JAVA实现简单的用户登录客户端
  8. Android仿支付宝高顶部功能条伸缩动画
  9. 集合点(掌握)-并发
  10. java使用poi.xssf 写入内容到excel表格中 和 读取 表格里面的数据