VIjos 大整数(超级恶心的高精)
Posted 心之所向 素履以往
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VIjos 大整数(超级恶心的高精)相关的知识,希望对你有一定的参考价值。
背景
很久很久以前,有个整数很大很囧
描述
一个k(1<=k<=80)位的十进制正整数N,就是所谓的大整数.
请你设计程序,对于给出的某一个大整数N,找到满足p^3+p^2+3p<=n的p的最大值.
格式
输入格式
输入数据只有一行,是一个K位的大整数N,行首行未无多余空格
输出格式
输出第一行为你所找到的P最大值,行首行末别乱加东西
样例1
样例输入1
1000000000000001000000000000003000000000000001
样例输出1
1000000000000000
1 /* 2 一道不错的高精练手题 3 先确定p的位数 4 然后从大到小找合适的p 5 k最多80位 6 p那最多 28位 7 假设每一位都用0-9试一遍 8 最多试不超过300遍 9 即使加上高精复杂度也不会太高 10 */ 11 #include<cstdio> 12 #include<cstring> 13 #include<iostream> 14 #define MAXN 1010 15 16 using namespace std; 17 18 char s[MAXN]; 19 20 int a[MAXN],b[MAXN],c[MAXN],e[MAXN],n[MAXN],_w; 21 22 inline bool judge() { 23 if(e[0]<n[0]) return true; 24 if(e[0]>n[0]) return false; 25 for(int i=n[0];i>=1;i--) { 26 if(e[i]>n[i]) return false; 27 if(e[i]<n[i]) return true; 28 } 29 return true; 30 } 31 32 inline void check() { 33 for(int i=1;i<=a[0];i++) { 34 if(a[i]<0) { 35 a[i+1]--; 36 a[i]+=10; 37 } 38 } 39 while(a[0]>1&&!a[a[0]]) a[0]--; 40 return; 41 } 42 43 inline void _pluss() { 44 a[_w]++; 45 a[0]++; 46 for(int i=1;i<=a[0];i++) { 47 if(a[i]>=10) { 48 a[i+1]++; 49 a[i]-=10; 50 } 51 } 52 while(a[0]>0&&!a[a[0]]) a[0]--; 53 return; 54 } 55 56 inline void __mul() { 57 for(int i=0;i<=a[0];i++) b[i]=a[i]; 58 c[0]=a[0]+b[0]+1; 59 for(int i=1;i<=a[0];i++) 60 for(int j=1;j<=b[0];j++) 61 c[i+j-1]+=a[i]*b[j]; 62 for(int i=1;i<=c[0];i++) 63 if(c[i]>=10) { 64 c[i+1]+=c[i]/10; 65 c[i]%=10; 66 } 67 while(c[0]&&!c[c[0]]) c[0]--; 68 for(int i=c[0];i>=0;i--) b[i]=c[i],c[i]=0; 69 c[0]=a[0]+b[0]+1; 70 for(int i=1;i<=a[0];i++) 71 for(int j=1;j<=b[0];j++) 72 c[i+j-1]+=a[i]*b[j]; 73 for(int i=1;i<=c[0];i++) 74 if(c[i]>=10) { 75 c[i+1]+=c[i]/10; 76 c[i]%=10; 77 } 78 while(c[0]&&!c[c[0]]) c[0]--; 79 e[0]=max(e[0],c[0])+1; 80 for(int i=1;i<=e[0];i++) { 81 e[i]+=c[i]; 82 if(e[i]>=10) { 83 e[i+1]+=e[i]/10; 84 e[i]%=10; 85 } 86 } 87 while(e[0]&&!e[e[0]]) e[0]--; 88 memset(c,0,sizeof c); 89 memset(b,0,sizeof b); 90 } 91 92 inline void _mul() { 93 for(int i=0;i<=a[0];i++) b[i]=a[i]; 94 c[0]=a[0]*2+1; 95 for(int i=1;i<=a[0];i++) 96 for(int j=1;j<=b[0];j++) 97 c[i+j-1]+=a[i]*b[j]; 98 for(int i=1;i<=c[0];i++) 99 if(c[i]>=10) { 100 c[i+1]+=c[i]/10; 101 c[i]%=10; 102 } 103 while(c[0]&&!c[c[0]]) c[0]--; 104 e[0]=max(e[0],c[0])+1; 105 for(int i=1;i<=e[0];i++) { 106 e[i]+=c[i]; 107 if(e[i]>=10) { 108 e[i+1]+=e[i]/10; 109 e[i]%=10; 110 } 111 } 112 while(e[0]&&!e[e[0]]) e[0]--; 113 memset(c,0,sizeof c); 114 memset(b,0,sizeof b); 115 } 116 117 inline void pluss() { 118 for(int i=1;i<=a[0];i++) b[i]=0; 119 b[0]=a[0]+1; 120 for(int i=1;i<=b[0];i++) { 121 b[i]+=3*a[i]; 122 if(b[i]>=10) { 123 b[i+1]+=b[i]/10; 124 b[i]%=10; 125 } 126 } 127 while(b[0]&&!b[b[0]]) b[0]--; 128 e[0]++; 129 for(int i=1;i<=b[0];i++) { 130 e[i]+=b[i]; 131 if(e[i]>=10) { 132 e[i+1]+=e[i]/10; 133 e[i]%=10; 134 } 135 } 136 while(e[0]&&!e[e[0]]) e[0]--; 137 } 138 139 int main() { 140 scanf("%s",s); 141 int len=strlen(s); 142 n[0]=len; 143 for(int i=1;i<=len;i++) n[i]=s[len-i]-48; 144 int _len=len/3+1;//因为有p^3 145 a[0]=_len; 146 a[_len]=0; 147 _w=_len; 148 while(true) { 149 if(!judge()) { 150 a[_w]--; 151 check(); 152 _w--; 153 if(_w==0) break; 154 a[_w]=1; 155 } 156 else _pluss(); 157 memset(e,0,sizeof e); 158 __mul(); 159 _mul(); 160 pluss(); 161 } 162 for(int i=a[0];i>=1;i--) printf("%d",a[i]); 163 return 0; 164 }
以上是关于VIjos 大整数(超级恶心的高精)的主要内容,如果未能解决你的问题,请参考以下文章