POJ 大数篇(POJ+百炼)
写总结是为了记得更好,力求完善。
大整数加法:
很容易知道,大数输入是用字符串。
所以可以再定义两个数组an1[M +10],an2[M + 10]存放转换之后的大数,需要进行初始化为0,注意存放时应该从个位开始。存完之后开始相加之和存入an1[i],如果an1[i] > 9;an1[i + 1]++。
例题:百炼2981
#include<stdio.h>
#include<string.h>
#define M 200
int an1[M + 10];
int an2[M + 10];
char szLine1[M + 10];
char szLine2[M + 10];
int main()
{int i,j;scanf("%s%s",szLine1,szLine2);memset(an1,0,sizeof(an1));memset(an2,0,sizeof(an2));j = 0;for(i = strlen(szLine1) - 1;i >= 0; i--)an1[j++] = szLine1[i] - '0';j = 0;for(i = strlen(szLine2) - 1;i >= 0; i--)an2[j++] = szLine2[i] - '0';for(i = 0;i < M; i++){an1[i] += an2[i];if(an1[i] >= 10){an1[i] -= 10;an1[i + 1]++;}}bool flag = false;for(i = M;i >= 0; i--) //也可以删除0 = Mif(flag)printf("%d",an1[i]);else if(an1[i]){printf("%d",an1[i]);flag = 1;}if(flag == false) //注意0+0的情况printf("0\n");printf("\n");return 0;
}
例题:POJ1503
这道题是;连续输入大数,直到输入到0。
法一:
还是按着之前的套路来,开数组,初始化,字符转化到数组,相加,输出。
#include<stdio.h>
#include<string.h>
#define M 105
int an1[M + 10];
int an2[M + 10];
char szLine[M + 10];
int main()
{int i,j,length;memset(an1,0,sizeof(an1));while(scanf("%s",szLine) != EOF){memset(an2,0,sizeof(an2));length = strlen(szLine);j = 0;for(i = length - 1;i >= 0; i--)an2[j++] = szLine[i] - '0';for(i = 0;i < M; i++){an1[i] += an2[i];if(an1[i] > 9){an1[i] -= 10;an1[i + 1]++;}}bool flag = false;if(strcmp(szLine,"0") == 0){for(i = M;i >= 0; i--)if(flag)printf("%d",an1[i]);else if(an1[i]){printf("%d",an1[i]);flag = true;}printf("\n");memset(an1,0,sizeof(an1));}}return 0;
}
法二:
#include<stdio.h>
#include<string.h>
#define M 105
int main()
{int i,an1[M + 10] = {0},length;char szLine[M + 10];while(scanf("%s",szLine) != EOF){length = strlen(szLine);int k = M;for(i = length - 1;i >= 0; i--){ //直接进行倒着运算,M为个位an1[k] += szLine[i] - '0';if(an1[k] > 9){an1[k] -= 10;an1[k - 1]++;}k--;}if(strcmp(szLine,"0") == 0){for(i = 0;i <= M; i++)if(an1[i]) break;for( ;i <= M; i++)printf("%d",an1[i]);printf("\n");memset(an1,0,sizeof(an1));}}return 0;
}
大数相乘:大部分算法都和大数相加一样,开两个数组an1[M + 10从,an2[M + 10]个位存放大数,不同的是乘法在计算的时候需要an2[i]去乘以an1的每一位,乘的结果累加到新开的数组aResult[i+j];这里有一个规律就是一个数的第i为位和另一个数相乘的结果一定要累加到第i+j位。比如16*12,第一次用an2[0]乘以an1[0]得到aResult[0 + 0] = 12,an[0]*an1[1] = 2;第二次an2[1]*an1[0] = 6累加到aResult[1+0]中得8,an2[1]*an1[1] = 1,累加到aResult[2]得到1;这样aResult中个位十位百位分别为12,8,1;然后统一处理进位问题得到2,9,1;结果便是192。
例题:百炼2980
#include<stdio.h>
#include<string.h>
#define M 200
int an1[M + 10];
int an2[M + 10];
int aResult[M*2 + 10];
char szLine1[M + 10];
char szLine2[M + 10];
int main()
{int i,j;scanf("%s%s",szLine1,szLine2);int length1,length2;length1 = strlen(szLine1);length2 = strlen(szLine2);memset(an1,0,sizeof(an1));memset(an1,0,sizeof(an2));memset(aResult,0,sizeof(aResult));j = 0;for(i = length1 - 1;i >= 0; i--)an1[j++] = szLine1[i] - '0';j = 0;for(i = length2 - 1;i >= 0; i--)an2[j++] = szLine2[i] - '0';for(i = 0;i < length2; i++)for(j = 0;j < length1; j++)aResult[j + i] += an1[j] * an2[i]; //注意累加for( i = 0;i < M*2; i++)if(aResult[i] > 9){aResult[i + 1] += aResult[i]/10; //注意累加aResult[i] %= 10;}bool flag = false;for(i = M*2;i >= 0; i--)if(flag)printf("%d",aResult[i]);else if(aResult[i]){printf("%d",aResult[i]);flag = true;}if(!flag)printf("0\n");printf("\n");return 0;
}
例题:POJ1001
对于这种复杂的高精度处理要条理清晰。最后的核心算法都是套路。
/*需要注意的点太多了,没事就多打几遍*/
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int point;
void ridzero(char a[])
{int i;i = strlen(a) - 1;while(a[i] == '0'){a[i] = '\0';i--;}
}
void ridpoint(char a[])
{int i,length;length = strlen(a);for(i = 0;i < length; i++) //判断是否有小数点if(a[i] == '.')break;if(i != length){for(i = length - 1;i >= 1; i--) //记录小数点的位置if(a[i] != '.') point ++;else break;if(a[0] == '0'){ //小数点有两种情况,一是0.0***的形式,去除小数点for(i = 2;i < length; i++)if(a[i] != '0'){strcpy(a,&a[i]);break;}}else { //这是***.**的形式,去除小数点int flag = 0;for(i = 1;i < length - 1; i++){if(a[i] == '.') flag = 1;if(flag) a[i] = a[i + 1];}a[i] = '\0';}}
}
void multiplication(char a[],char b[])
{int length1 = strlen(a),length2 = strlen(b);int i,j,an1[210],an2[210],aResult[420];memset(an1,0,sizeof(an1));memset(an2,0,sizeof(an2));memset(aResult,0,sizeof(aResult));j = 0;for(i = strlen(a) - 1;i >= 0; i--)an1[j++] = a[i] - '0';j = 0;for(i = strlen(b) - 1;i >= 0; i--)an2[j++] = b[i] - '0';for(i = 0;i < length2; i++)for(j = 0;j < length1; j++)aResult[i + j] += an1[j] * an2[i];for(i = 0;i < 410; i++)if(aResult[i] >= 10){aResult[i + 1] += aResult[i]/10;aResult[i] %= 10;}bool flag = false;j = 0;for(i = 410;i >= 0; i--)if(flag) a[j++] = aResult[i] + '0';else if(aResult[i]){a[j++] = aResult[i] + '0';flag = 1;}a[j] = '\0';
}
void show(char a[])
{int i,length;length = strlen(a);if(point >= length){printf(".");for(i = point - length;i > 0; i--)printf("0");printf("%s\n",a);}else {for(i = 0;i < length; i++)if(length - point == i){cout<<"."<<&a[i];break;}else cout<<a[i];cout<<endl;}
}
int main()
{int i,n;char str1[210],str2[210];while(cin>>str1>>n){if(n == 0){printf("1\n");continue;}point = 0;ridzero(str1); //去掉多余的零ridpoint(str1); //去掉小数点strcpy(str2,str1);for(i = 1;i < n; i++)multiplication(str1,str2); //核心算法,大数相乘point *= n; //记录小数点的位置show(str1);}return 0;
}
POJ 大数篇(POJ+百炼)相关推荐
- POJ 2481 Cows POJ 2352 Stars(树状数组妙用)
题目链接:POJ 2481 Cows POJ 2352 Stars 发现这两个题目都跟求逆序数有着异曲同工之妙,通过向树状数组中插入点的位置,赋值为1,或者++,然后通过求和来判断比当前 点 &quo ...
- Bailian2972 确定进制(POJ NOI0113-34,POJ NOI0201-1973)【暴力+进制】
问题链接:POJ NOI0113-34 确定进制. 问题链接:POJ NOI0201-1973 确定进制. 确定进制 描述 6*9 = 42 对于十进制来说是错误的,但是对于13进制来说是正确的.即, ...
- Bailian2786 Pell数列【数列】(POJ NOI0102-1788,POJ NOI0103-1788)
问题链接:POJ NOI0102-1788 Pell数列. 问题链接:POJ NOI0103-1788 Pell数列. Pell数列 描述 Pell数列a1, a2, a3, ...的定义是这样的,a ...
- poj解题报告——poj 1528 Perfection
原题入口 poj 1528 Perfection 题目描述 Perfection Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- POJ 2352 Starts POJ 2418 Cows
两道相似的题,都可以转化为求一个点的某个方位(左上,左下,右上,右下)有多少个点,求和 POJ 2352 Starts Astronomers often examine star maps wher ...
- 【大数篇】加法--减法篇
对于非常大的数据我们需要用数组进行存储数据呀 加法--- 由于数组下标是由0开始的,所以我们在考虑进位的时候应该向他下标增大的方向进位. but,在输入数据时我们的个位是最后输入,要让它到第一位 ...
- 字符串专题:map POJ 1002
第一次用到是在'校内赛总结'扫地那道题里面,大同小异 map<string,int>str 可以专用做做字符串的匹配之类的处理 string donser; str [donser]++ ...
- poj 2411 2663 3420 点头1033
poj 2411 http://poj.org/problem?id=2411 题意:让你用1*2的矩阵去填满n*m的方格,有多少种方法 题解:http://blog.csdn.net ...
- 分治应用--最近点对问题 POJ 3714
文章目录 1. 问题描述 2. 解题思路 3. 实现代码 4. POJ 3714 1. 问题描述 二维平面上有n个点,如何快速计算出两个距离最近的点对? 2. 解题思路 暴力做法是,每个点与其他点去计 ...
最新文章
- JavaWeb-JavaMail邮件开发
- datacombo重复值的处理_Pandas入门【S1E3】缺失值和重复值处理
- 鸿蒙os终于开始大升级,华为鸿蒙OS终于要迎来大规模推送升级了
- Azure人工智能认知服务(AI·机器学习)
- uniapp网络请求获取数据_2.uni-app 发起网络请求
- python读取多个文件夹_如何从python中的文件夹中读取多个NetCDF文件
- 以太坊节点开放RPC端口容易被攻击及网络安全配置笔记
- Linux下禁止使用swap及防止OOM机制导致进程被kill掉
- Amoeba及其类似产品
- 查看VS2017编译器 cl.exe 位置
- 安装GitHub安装步骤
- NVIDIA 驱动和CUDA下载官网地址
- 登录时候输入验证码,验证码图片从服务器获取方法
- (转)爆款游戏推动硬件普及,5G 促进 VR 产业规模化运用
- 破解大众点评字体反爬
- python网络爬虫——自学笔记2.1用requests库和re库爬取图片
- oracle rat结果分析比较,Oracle RAT介绍及最佳实践
- 计算机用户名怎么改好听,电脑版本优酷视频如何设置呢称_昵称起名
- “热散由心静,凉生为室空” - linux温控的那些事儿
- html图像标签、绝对路径和相对路径
热门文章
- 分形 java_java实现分形
- 失眠不仅仅是睡不着,出现这些情况也算失眠
- CodeForces - 750D New Year and Fireworks(模拟+滚动数组记录)
- CockroachDB介绍
- 2022年全球与中国NAND闪存市场现状及未来发展趋势
- hdu 1045Fire Net (建图 、二分匹配)
- DBeaver执行sql脚本报错:CreateProcess error=193, %1 不是有效的 Win32 应用程序。
- 一个函数调用另一个函数中的结果_xing2516_新浪博客
- “普通劳动者”的高学费能否“普通”?
- 第十七届全国大学智能汽车竞赛全国总决赛名单