福田附近网站开发公司,wordpress织梦扩展,广告营销图片,网站建设的客户怎么找引入
首先了解#xff1a; 1. int 范围为10^9 2. long long 范围数量级为10^18
如果超过该数量级#xff0c;该怎么办#xff1f; ——这就是高精度、大数的算法问题
加法 输入两个整数a,b,输出他们的和#xff08;10的500次方#xff09; 核心是加法的核心——》每…引入
首先了解 1. int 范围为10^9 2. long long 范围数量级为10^18
如果超过该数量级该怎么办 ——这就是高精度、大数的算法问题
加法 输入两个整数a,b,输出他们的和10的500次方 核心是加法的核心——》每个数的结果等于这个位置的a,b加上上一个位置的进位c c[i]a[i]b[i];//的原因是它要加上上一位的进位上一位的进位早已存储在c[i]里面了
c[i1]c[i]/10;//算出进位的数字
c[i]%10;//这个位置的数字 算法核心代码给出来了下面就是要实践了。
题目 https://www.luogu.com.cn/problem/P1601 ——就是这个题目输入两个整数a,b,输出他们的和10的500次方 #includebits/stdc.husing namespace std;char s1[1000],s2[1000];
int a[1000],b[1000],c[1000];int main()
{scanf(%s,s1);//数组本身代表地址不用加scanf(%s,s2);int mstrlen(s1);int nstrlen(s2);//确定长度以确保可以把所有字母转化为数字for(int i0;im;i){a[m-i-1]s1[i]-0;//假设输入1233应该是最先计算的但它位于最后一位a和b的位数不一定一样所以要倒置数组}for(int i0;in;i){b[n-i-1]s2[i]-0;}mmax(m,n)1;//1是为了以防进位for(int i0;im;i){c[i]a[i]b[i];c[i1]c[i]/10;c[i]%10;}//由于可能出现输出的最高位为0也就是c[m]但也有输出结果为0的情况所以需要进行修改nm-1;if(c[n]0m0){m--;//最大值减1}for(int im-1;i0;i--)//?{printf(%d,c[i]);}return 0;
} 另一种写法为
#includebits/stdc.husing namespace std;char s1[1000],s2[1000];
int a[1000],b[1000],c[1000];int main()
{scanf(%s,s1);//数组本身代表地址不用加scanf(%s,s2);int mstrlen(s1);int nstrlen(s2);//确定长度以确保可以把所有字母转化为数字for(int i0;im;i){a[m-i]s1[i]-0;//假设输入1233应该是最先计算的但它位于最后一位a和b的位数不一定一样所以要倒置数组}for(int i0;in;i){b[n-i]s2[i]-0;}mmax(m,n)1;//1是为了以防进位for(int i1;im;i){c[i]a[i]b[i];c[i1]c[i]/10;c[i]%10;}//由于可能出现输出的最高位为0也就是c[m]但也有输出结果为0的情况所以需要进行修改if(c[m]0m0){m--;//最大值减1}for(int im;i0;i--)//?{printf(%d,c[i]);}return 0;
} 他们的区别在于在倒置数组时一个让数组a,b从0开始一个让数组从1开始计算。
Tips 1. 做加法时由于要每一位的数字所以为了简便先都输入到char数组中再转化为数字 2. 转化成数字的时候记得要倒置数组——》加法计算从最低位计算所以要把本身最后存进去的数字放到第一次计算的位置 3. 记得要更新c也就是答案数组的长度 4. 记得最后判断c的最高位为0且其长度不为0不是000这种情况时不要输出这个最高位. 5. 最后输出要从最高位输出 减法 依旧是高精度题目 先随便列一个减号方程一位一位的减 然后我们观察到一下规律 1. 如果a[i]b[i]则直接相减出结果即可 2. 如果a[i]b[i]需要借位 a[i1]--; 答案等于a[i]-b[i]10; 根据规律我们可以写出代码
if(a[i]b[i]){c[i]-b[i];
}else
{c[i]a[i]-b[i]10;a[i1]--;
} 但是需要注意一点——a一定要比b大不然整体输出会是负数如果不是可以把a和b进行交换。 除了这个部分其它都和加法没什么区别
题目 https://www.luogu.com.cn/problem/P2142
模板题代码
#includebits/stdc.h
using namespace std;char s1[10090], s2[10090], s3[10090];
int a[10090], b[10090], c[10090];bool compare(char *s1, char *s2) {int len1 strlen(s1);int len2 strlen(s2);if (len1 ! len2) return len1 len2; // 如果长度不同长的数更大for (int i 0; i len1; i) {if (s1[i] ! s2[i]) return s1[i] s2[i]; // 按位比较}return true; // 如果完全相同返回true
}int main() {scanf(%s, s1);scanf(%s, s2);if (!compare(s1, s2)) { // 如果s2比较大cout -;strcpy(s3, s1);strcpy(s1, s2);strcpy(s2, s3);}int m strlen(s1);int n strlen(s2);for (int i 0; i m; i) {a[m - i] s1[i] - 0;}for (int i 0; i n; i) {b[n - i] s2[i] - 0;}m max(m, n);for (int i 1; i m; i) {if (a[i] b[i]) {a[i 1]--;a[i] 10 ;} c[i] a[i] - b[i];}while (m 1 c[m] 0) m--; // 去除前导零for (int i m; i 0; i--) {printf(%d, c[i]);}return 0;
}
乘法 还是分析如果要一步步得去计算a乘b。 从中得出规律 1. 乘数从最低位开始取没取一位都要和被乘数相乘也就是被乘数的每一位乘以这位数字。 2. 假如乘以这位数字结果大于10则需要进位10位数进位个位数留下 3. 把最后的结果错位相加即可 我们可以用字母来替代数字从而观察如何错位相加——例如a4a3a2a1乘b3b2b1 通过计算我们可以发现假如结果存储在c数组中那么aibj对应的是cij-1的位置
得出代码
c[ij-1]a[i]*b[j];
c[ij]c[ij-1]/10;//算出要进位的数字这个用是因为c[ij-1]通常不止一个
c[ij-1]%10;//算出留下来的这一位 题目
https://www.luogu.com.cn/problem/P1303
代码
#includebits/stdc.husing namespace std;char s1[2009],s2[2009];
int a[2009],b[2009],c[4009];int main()
{scanf(%s,s1);scanf(%s,s2);int lastrlen(s1);int lbstrlen(s2);for(int i0;ila;i){a[la-i]s1[i]-0;}for(int i0;ilb;i){b[lb-i]s2[i]-0;}int lclalb;for(int i1;ila;i){for(int j1;jlb;j){c[ij-1]a[i]*b[j];c[ij]c[ij-1]/10;c[ij-1]%10;}}while(c[lc]0lc1){lc--;}for(int ilc;i0;i--){printf(%d,c[i]);}return 0;
}总结
根据题目和代码我们知晓了如何利用简单方法来计算高精度的题目还需要注意的是创建数组的大小时往往设置为设置精度的次方数 例如如果说明数范围为10的10086次方那么如果是加减法那么所有的数组大小都为【10090】//多一点保险 如果是乘法那么需要让c数组也就是存储结果的数组2倍的【10090】