目录
一,题目
描述
输入一个大于0的大整数N,长度不超过100位,要求输出其除以13得到的商和余数。
输入描述
一个大于0的大整数,长度不超过100位。
输出描述
两行,分别为整数除法得到的商和余数。
用例输入 1
2132104848488485
用例输出 1
164008065268345 0
二,思路
- 根据题目,可知处理的是大整数,输入的数超出了标准的数据类型,因此,可以考虑使用string字符串或者是vector容器,一般来说,只要是输入大数据的情况就选择string字符串来存储数据,如果是运算过程中产生的大数据,就选择vector容器。
string s; cin>>s;
除法运算会产生两个整型数据:
一个是商(我用容器z来存储),另外一个是余(我用容器y来存储)vector<int> z(1,0),y(1,0);
如上,我声明了两个容器,这两个容器中都只有一个元素0(运算后会重新赋值)。
-
列竖式计算一个整数的商和余,假设输入的被除数s=“12345”,列出的竖式如下:
可以看到,由于除数是两位数,一开始在算的时候,就需要先取出被除数的前两位来进行计算,得到商的第一个计算结果,及余的第一个计算结果:z[0]=((s[0]-'0')*10+s[1]-'0')/13; // 字符减去字符'0'返回字符所包含的数(返回整型) y[0]=(((s[0]-'0')*10+s[1]-'0')%13)*10+s[2]-'0';
不管是商还是余都跟被除数的总长度有关,所以我声明并定义了一个整型变量l来存储输入的被除数总长度:
int l=s.size();
for循环遍历次数小于输入的被除数长度,由于字符串最后一位是空格,因此遍历条件中的局部变量 i 需要再减 1。
for(int j=1;j<l-1;j++){}
之后商的运算跟被除数的第一位无关,只与算出来的余数及被除数接下来的对应位有关(通过观察并找规律),不难发现,只要被除数还有位数就需要将余数乘10,再加上被除数接下来要被遍历到的位,形成一个新的被除数。(重复循环运算)
z.push_back(y[j-1]/13); y.push_back((j+1<l-1)?y[j-1]%13*10+s[j+2]-'0':y[j-1]%13);
求余的代码之所以要加上三元运算符的判断,是因为当遍历到被除数 s 的倒数第三位(包括结尾的空格)时,就是余最终的计算结果,不需要再进行乘十操作
-
输出商的时候,考虑到可能有前导0的存在,循环变量 i 的初始值就会有两种情况:
①当商没有前导0时,i从0开始。
②当商有前导0时, i从没有前导0的索引下标开始。
由于题目已经给出了除数 13 的位数 为 2,因此,如果存在前导0,只会有一个,位于z[0]中,因此,给个三元运算:
i=(z[0]>0)?0:1 // 如果z[0]等于0,i 取值为 1,否则 i 取值为 0,对应代码如下👇for(int i=(z[0]>0)?0:1;i<l-1;i++){ cout<<z[i]; }
-
最后输出余。存储余的容器y的最后一个元素(被初始化过)s.size()-1为空格'\0',倒数第二个才是所求余的最终计算结果,直接输出即可。
cout<<endl<<y[l-2];
因为题目要求商和余需要换行输出,所以在输出余之前需要先输出endl进行换行。
相关代码如下👇
三,代码
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin>>s;
vector<int> z(1,0),y(1,0);
int l=s.size();
z[0]=((s[0]-'0')*10+s[1]-'0')/13;
y[0]=(((s[0]-'0')*10+s[1]-'0')%13)*10+s[2]-'0';
for(int j=1;j<l-1;j++){
z.push_back(y[j-1]/13);
y.push_back((j+1<l-1)?y[j-1]%13*10+s[j+2]-'0':y[j-1]%13);
}
for(int i=(z[0]>0)?0:1;i<l-1;i++){
cout<<z[i];
}
cout<<endl<<y[l-2];
return 0;
}
有问题请在评论区留言或者是私信我,回复时间不超过一天。