[code3119]高精度练习之大整数开根


试题描述

 给出一个正整数n,求n开根号后的整数部分的值。n的位数不超过1000位。

输入

读入一个不超过1000位的正整数n。

输出

输出所求答案

输入示例

17  

输出示例

4

高精度开根:需要用的是手算开平方根的方法,我其实这个方法也不会,是临时到网上学习的

网上说的方法都挺详细的,我在这里就不详细说了,下面直接贴代码:

高精度模板需要用到高减高,高乘低,高加低。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<queue>
  6 #include<cstdio>
  7 using namespace std;
  8 typedef long long LL;
  9 inline int read()
 10 {
 11     int x=0,f=1;char c=getchar();
 12     while(!isdigit(c)){if(c==‘-‘)f=-1;c=getchar();}
 13     while(isdigit(c)){x=x*10+c-‘0‘;c=getchar();}
 14     return x*f;
 15 }
 16 const int maxn=1010;
 17 struct data
 18 {
 19     int l,v[maxn];
 20     data(){l=1;memset(v,0,sizeof(v));}
 21     data operator = (const data& s)
 22     {
 23         l=s.l;memset(v,0,sizeof(v));
 24         for(int i=1;i<=l;i++)v[i]=s.v[i];
 25         return *this;
 26     }
 27     data operator = (const int& s)
 28     {
 29         l=1;v[1]=s;
 30         while(v[l]>9)v[l+1]+=v[l]/10,v[l]%=10,l++;
 31         return *this;
 32     }
 33     data operator - (const data& s)
 34     {
 35         data c;c.l=l;
 36         for(int i=1;i<=c.l;i++)c.v[i]=v[i];
 37         for(int i=1;i<=c.l;i++)c.v[i]-=s.v[i];
 38         for(int i=1;i<c.l;i++)if(c.v[i]<0)c.v[i]+=10,c.v[i+1]--;
 39         while(!c.v[c.l])c.l--;
 40         return c;
 41     }
 42     data operator * (const int& s)
 43     {
 44         data c;c.l=l;
 45         for(int i=1;i<=c.l;i++)c.v[i]=v[i]*s;
 46         for(int i=1;i<c.l;i++)if(c.v[i]>9)c.v[i+1]+=(c.v[i])/10,c.v[i]%=10;
 47         while(c.v[c.l]>9)c.v[c.l+1]+=(c.v[c.l])/10,c.v[c.l]%=10,c.l++;
 48         return c;
 49     }
 50     data operator + (const int& s)
 51     {
 52         data c=*this;
 53         c.v[1]+=s;int i=1;
 54         while(c.v[i]>9)c.v[i+1]+=c.v[i]/10,c.v[i]%=10,i++;
 55         c.l=max(c.l,i);
 56         return c;
 57     }
 58     bool operator <= (const data& t)const
 59     {
 60         if(l!=t.l)return l<t.l;
 61         for(int i=l;i;i--)if(v[i]!=t.v[i])return v[i]<t.v[i];
 62         return 1;
 63     }
 64 }a;
 65 int num[510];
 66 void scan(data &s)
 67 {
 68     char ch[maxn];
 69     scanf("%s",ch+1);s.l=strlen(ch+1);
 70     for(int i=1;i<=s.l;i++)s.v[i]=ch[s.l-i+1]-‘0‘;
 71     return;
 72 }
 73 void print(data s){for(int i=s.l;i;i--)printf("%d",s.v[i]);cout<<endl;}
 74 void init(data s)//将这个数从个位起,向左每两位分一节(例如65536变成6,55,36)
 75 {
 76     if(s.l%2)
 77     {
 78         num[0]=s.v[s.l];
 79         for(int i=2;i<=s.l;i+=2)num[i/2]=s.v[s.l-i+1]*10+s.v[s.l-i];
 80     }
 81     else for(int i=1;i<=s.l;i+=2)num[i/2]=s.v[s.l-i+1]*10+s.v[s.l-i];
 82     return;
 83 }
 84 data Sqrt(data s)
 85 {
 86     data ans,t,q,p;
 87     ans=0;t=0;
 88     int len= s.l%2 ? s.l/2+1 : s.l/2;//划分块的数量
 89     for(int i=0;i<len;i++)
 90     {
 91         t=(t*100)+num[i];
 92         p=ans*20;ans=ans*10;//这里的ans要提前乘以10,如果下面的循环一次都没进去的话,ans就不会更新了
 93         for(int j=9;j>=0;j--)
 94         {
 95             q=(p+j)*j;
 96             if(q<=t)
 97             {
 98                 ans=ans+j;
 99                 t=t-q;
100                 break;
101             }
102         }
103     }
104     return ans;
105 }
106 int main()
107 {
108     scan(a);
109     init(a);
110     print(Sqrt(a));
111     return 0;
112 }
时间: 2024-08-24 17:17:46

[code3119]高精度练习之大整数开根的相关文章

codevs 3119 高精度练习之大整数开根 (各种高精+压位)

/* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms 测试点#2.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms 测试点#3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms 测试点#4.in 结果:AC 内存使用量: 256kB 时间使用量: 10ms 测试点#5.in 结果:AC 内

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

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

大整数类BIGN的设计与实现 C++高精度模板

首先感谢刘汝佳所著的<算法竞赛入门经典>. 众所周知,C++中储存能力最大的unsigned long long 也是有着一个上限,如果我们想计算非常大的整数时,就不知所措了,所以,我写了一个高精度类,允许大整数的四则运算 这个类利用字符串进行输入输出,并利用数组进行储存与处理,通过模拟四则运算,可以计算很大的整数的加减乘除比大小. 贴上我的代码: #include<string> #include<iostream> #include<iosfwd> #i

COJ 1211 大整数开平方

手写求大整数开根号所得到的值,具体计算过程参考别人的资料,最后利用java的大整数得到答案 别人博客链接:http://www.cnblogs.com/Rinyo/archive/2012/12/16/2820450.html 1.举例 上式意为65536的开平方为256.手开方过程类似于除法计算.为了方便表述,以下仍称类似位置的数为“被除数”.“除数”.“商”. 以65536为例,其具体计算过程如下: Step1:将被开方数(为了形象,表述成“被除数”,此例中即为65536)从个位往高位每两位

【HNOI2004】【BZOJ1213】高精度开根

Description 晓华所在的工作组正在编写一套高精度科学计算的软件,一些简单的部分如高精度加减法.乘除法早已写完了,现在就剩下晓华所负责的部分:实数的高精度开m次根.因为一个有理数开根之后可能得到一个无理数,所以这项工作是有较大难度的.现在要做的只是这项工作的第一步:只对自然数进行开整数次根,求出它的一个非负根,并且不考虑结果的小数部分,只要求把结果截断取整即可.程序需要根据给定的输入,包括需要开根的次数,以及被开根的整数:计算出它的非负根取整后的结果. Input 共有两行,每行都有一个

【BZOJ1213】高精度开根

python是坠吼的! 原题: 不贴原题,就是高精度开根,结果向下取整 首先二分答案,高精度嘛--python即可 二分右端点设为n会T掉,需要先倍增一个r,while(r **m <= n)  r *= 2 然后T掉了,代码如下,亮点自寻 1 m, n = input(), input() 2 l, r = 0, n 3 while r ** m < n: 4 r *= 2 5 6 while(l + 1 < r): 7 md = (l + r) >> 1 8 if(md

模板 高精度大整数

#include<bits/stdc++.h> #define clr(x,y) memset((x),(y),sizeof(x)) using namespace std; typedef long long LL; const int MaxL=400; //大数长度 //大整数 //减法只能大减小 struct bign { int len, s[MaxL]; //构造函数 bign () { memset(s, 0, sizeof(s)); len = 1; } bign (int n

uva 424(Integer Inquiry)高精度大整数加法

这是一道很标准的大整数加法,我却wa了4次,没提交一次就查到一些细节问题,比如说我们考虑前导 0的问题,还有就是没有对输入数组处理, 使得他们每次输入时高位的置0,还有就是没考虑到最后相加后的进位, 这些问题一一改正之后,还是wa了,原来是因为,我把if语句中的==只写了一个...真坑啊,,,我就说怎么会 不过,明明写的对的,大数相加竟然还wa了四次,还有就是这道题最后不写换行也会wa...看来还是有必要从基础练起提高代码能力: 贴代码: #include<stdio.h> #include&

BZOJ 1213 HNOI2004 高精度开根 二分+高(Py)精(thon)度

题目大意:求n^(1/m) 一大早水个Python- - 直接开根尼玛过不去- - 需要二分- - m,n=int(raw_input()),int(raw_input()) l,r=0,1 while r**m<=n: l=r;r=r*2 while l+1<r: mid=(l+r)//2 if mid**m<=n: l=mid else: r=mid if r**m<=n: print r else: print l