分析:使用的是构造新数字法进行不断构造,然后逼近每一位数字,然后使用c++徒手敲了240多行代码,竟然过了........................很有成就感。
代码如下:
===============================================================================================================================
#include<stdio.h> #include<algorithm> #include<vector> #include<iostream> #include<math.h> #include<string.h> using namespace std; const int MAXN = 2007; struct BigNum {///数值保存从0位开始 int Size;///数的位数 int num[MAXN];///数值,逆序保存 BigNum(){ Size=1; memset(num, false, sizeof(num)); } void Cin() { char s[MAXN]; scanf("%s", s); Size = strlen(s); for(int i=Size-1; i>=0; i--) num[i] = s[Size-i-1] - '0'; } bool operator <= (const BigNum &b)const { if(Size > b.Size)return false; if(Size < b.Size)return true; for(int i=Size-1; i>=0; i--) { if(num[i] > b.num[i])return false; if(num[i] < b.num[i])return true; } return true; } void operator = (const BigNum &b) { Size = b.Size; for(int i=0; i<b.Size; i++) num[i] = b.num[i]; } void operator = (const int &b) { int tem = b; if(b == 0) Size = 1; else Size = (int)(log10(tem)+0.00001)+1; for(int i=0; i<Size; i++) { num[i] = tem % 10; tem /= 10; } } BigNum operator <<(const int &k)const { BigNum tmp; for(int i=Size-1; i>=0; i--) { tmp.num[i+k] = num[i]; } tmp.Size = Size + k; tmp.CarryBit(); return tmp; } BigNum operator * (const BigNum &b)const { BigNum res; res.Size = Size + b.Size - 1; for(int i=0; i<b.Size; i++) for(int j=0; j<Size; j++) { res.num[i+j] += num[j] * b.num[i]; } res.CarryBit(); return res; } BigNum operator * (const int &b)const { BigNum res; res.Size = Size; for(int i=0; i<Size; i++) { res.num[i] = num[i] * b; } res.CarryBit(); return res; } BigNum operator + (const BigNum &b)const { BigNum res; res.Size = max(b.Size, Size); for(int i=0; i<res.Size; i++) res.num[i] = num[i] + b.num[i]; res.CarryBit(); return res; } BigNum operator + (const int &b)const { BigNum res; res = b; res.Size = max(res.Size, Size); for(int i=0; i<res.Size; i++) res.num[i] += num[i]; res.CarryBit(); return res; } BigNum operator - (const BigNum &b)const {///b值小,先比较在进行相减 BigNum res; res.Size = Size; for(int i=0; i<Size; i++) { if(i < b.Size) res.num[i] = num[i] - b.num[i]; else res.num[i] = num[i]; } res.CarryBit(); return res; } void CarryBit() {///进位,注意减法的时候进位结果需要是非负数 for(int i=0; i<Size; i++) { if(num[i] >= 10) { if(i+1==Size) { num[i+1] = 0; Size += 1; } num[i+1] += num[i]/10; num[i] %= 10; } else if(num[i] < 0) { num[i+1] -= 1; num[i] += 10; } } while(Size > 1 && !num[Size-1]) Size -= 1; } void Out() { for(int i=Size-1; i>=0; i--) printf("%d", num[i]); printf(" "); } }; int Find(const BigNum &a, BigNum &Mod) { int i; BigNum t; for(i=1; i<=9; i++) { t = (((a*2)<<1)+i) * i; if(t <= Mod) continue; break; } i--; t = (((a*2)<<1)+i) * i; Mod = Mod - t; return i; } BigNum Sqrt(const BigNum &a) { BigNum ans, Mod; int len=a.Size-1; if(a.Size % 2 == 0) { Mod = Mod + (a.num[len]*10+a.num[len-1]); len -= 2; } else { Mod = Mod + a.num[len]; len -= 1; } ans = Find(ans, Mod); while(len > 0) { Mod = (Mod<<2) + (a.num[len]*10+a.num[len-1]); ans = (ans<<1) + Find(ans, Mod); len -= 2; } return ans; } int main() { BigNum a; a.Cin(); a = Sqrt(a); a.Out(); return 0; }