强行刷段位第九天

今天感觉感冒基本好了。

就是还有鼻涕。

这个博客不像是用来记录刷题的,好像是用来记录感冒历程的(笑哭)

就当写日记了。。。反正没什么人看~

 

洗了个头,扫了个地。

该买一些洗发水什么的了,这回病好了,抽时间要去买点东西了。

现在感觉浑身充满了力量~又要开始间歇性踌躇满志了!

想过年前拔牙,这样过年就可以少吃点了。。。

 

突然有点舍不得减掉我的头发了。。。

因为前两天买了个帽子,本来是为了万一剪头发了不好看,可以戴着挡一挡。

结果发现这个帽子长卷发戴着更合适一点。。。

 

不管了~年前肯定是要剪的,作为2019的断舍离~

 

感冒好了话都变多了。。。

做题做题。


高精度第一题:

题目:

给出两个正整数A和B,计算A-B的值。保证A和B的位数不超过500位。

输入描述:

读入两个用空格隔开的正整数

输出描述:

输出A-B的值

样例输入:

3 12

样例输出:

-9

数据范围及提示:

两个正整数的位数不超过500位

我的答案:

这道题写完通过的时候我一脸呆滞。。。

就。。。通过了???

我明明只是要提交一下,获取一下出错用例,然后接着写啊。。。

我明明没有写0000001这种情况的处理啊。。。

好吧。。。

本着认真严谨的态度,我把去除0的工作加上了之后再次提交,成功通过,撒花花~

 

头一次写高精度,开始还是有点蒙,不过顺着字符串这个思路,暴力模拟下去还是不难想到的。

就酱。

 

哦,对,之前出了个小菜鸡没见过的错误。说我的minus函数ambiguous。

查了一下原来是minus和库函数重名,随手改了一下名字就通过啦。以后长记性~

#include <iostream>
#include <string.h>
using namespace std;  //测试数据:19987787889 98776665

int mark(char a[],char b[],int alen,int blen) //需要输出负号则返回1 
{
	int res=0;
	int i=0;
	if(alen<blen)  res=1;
    if(alen==blen)
	{
		for(i=0;i<alen;i++)
		{
			if(a[i]<b[i])
			{
				res=1;
				break;
			}
		}
	}
	
	return res;
}

void minuss(char a[],char b[],int alen,int blen) //保障 a>b
{
	int c[500];
	int arear=alen-1;
	int brear=blen-1;
	int i=0;
	int flag=0;
	while(arear>=0 && brear>=0)
	{
		if(a[arear]>=b[brear]) c[flag++]=a[arear]-b[brear];
		else
		{
			c[flag++]=10-b[brear]+a[arear];
			a[arear-1]--;
		}
		arear--;
		brear--;
	}
	
	while(arear>=0)
	{
		if(a[arear]>='0') c[flag++]=a[arear]-'0';
		else
		{
			c[flag++]=10-'0'+a[arear];
			a[arear-1]--;
		}
		arear--;
	}
	
	flag--;
	
	while(c[flag]==0)
	{
		flag--;
	}
		
	for(i=flag;i>=0;i--)
	{
		cout<<c[i];
	}	
 } 

int main()
{
	char a[500];
    char b[500]; 
	cin>>a>>b;
	
	int alen=0,blen=0,flag=0;
	alen=strlen(a);
	blen=strlen(b);

	flag=mark(a,b,alen,blen);  //输出符号 
	if(flag==1)
	{
		cout<<"-";
		minuss(b,a,blen,alen);
	}
	else minuss(a,b,alen,blen);
		
	return 0;
}

。。。

刚发出来就被Kevin大神看见了,

告诉我不能像上面那样获取错误用例,只能按照题目来写,正常机试提交只有一个结果正确或者错误

这样容易养成依赖,会觉得反正每次可以改错误样例。。。

我还以为我这是正常操作那~(委屈.jpg)

 

那么以后,就把各种情况都考虑好了再写。自己把测试用例想完善,测试好了再提交~

也会像某Kevin说的,每一次的错误都记录一下,比如没考虑到哪种情况等等。
 


高精度第二题:

题目:给出两个正整数A和B,计算A+B的值。保证A和B的位数不超过500位。

输入描述:

读入两个用空格隔开的正整数

输出描述:

输出A+B的值

样例输入:

3 12

样例输出:

15

数据范围及提示:

两个正整数的位数不超过500位

我的答案:

这题看似和上面一样,其实不太一样。

emmm

其实也一样。

 

这题出现了两个错误

1.同位的两个数相加小于10的情况下忘了将记录进位数的temp置0。导致接下来会加上了上一次的进位位。

2.这是加法,两个加数地位一样,假如两个数的位数不同,不能只考虑前面的数比后面的长这种情况,还要考虑后面的比前面的长。

 

代码:

#include <iostream>
#include <string.h>
using namespace std; 

void pluss(char a[],char b[],int alen,int blen) 
{
	int c[10000];
	int arear=alen-1;
	int brear=blen-1;
	int i=0,temp=0;
	int flag=0;
	while(arear>=0 && brear>=0)
	{
		if((temp+a[arear]-'0'+b[brear]-'0')<10)
		{
			c[flag++]=a[arear]-'0'+b[brear]-'0'+temp;
			temp=0;
		}
		else
		{
			c[flag++]=(a[arear]-'0'+b[brear]-'0'+temp)%10;
			temp=(a[arear]-'0'+b[brear]-'0'+temp)/10;
		}
		arear--;
		brear--;
	}
	
	while(arear>=0)
	{
		if((temp+a[arear]-'0')<10)
		{
			c[flag++]=a[arear]-'0'+temp;
			temp=0;
		}
		else
		{
			c[flag++]=(a[arear]-'0'+temp)%10;
			temp=(a[arear]-'0'+temp)/10;
		}
		arear--;
	}
	
	while(brear>=0)
	{
		if((temp+b[brear]-'0')<10)
		{
			c[flag++]=b[brear]-'0'+temp;
			temp=0;
		}
		else
		{
			c[flag++]=(b[brear]-'0'+temp)%10;
			temp=(b[brear]-'0'+temp)/10;
		}
		brear--;
	}
	
	if(temp!=0) c[flag]=temp;
	else flag--;
	
	for(i=flag;i>=0;i--)
	{
		cout<<c[i];
	}	
 } 

int main()
{
	char a[500];
    char b[500]; 
	cin>>a>>b;
	
	int alen=0,blen=0;
	alen=strlen(a);
	blen=strlen(b);

	pluss(a,b,alen,blen);
		
	return 0;
}

高精度第三题:

题目:

给出两个正整数A和B,计算A*B的值。保证A和B的位数不超过500位。

输入描述:

读入两个用空格隔开的正整数

输出描述:

输出A*B的值

样例输入:

3 12

样例输出:

36

数据范围及提示:

两个正整数的位数不超过500位

我的答案:

这个和前两题还是有差别的。

想了很久,一直在纠结怎么循环,才能把进位,当前的乘积加在一起。

就是没观察出来可以先加再进位这种方法。

Kevin大神果然还是强强的。

我还是太嫩了。。。

自己还是没抓到本质吧,主要是没想到先都加进c里,再统一进位这种办法。

积累经验吧。

Kevin说得对,任何题目都是这样,想一下假如人算的话,怎么做,然后应用到电脑上,然后利用算法和数据结构优化时间和空间复杂度。

就算是要模拟,也不能一模一样的蛮干。有脑子就要学会转弯,学会转弯就是能够优化。

下面是Kevin大神教给我的代码:

(不到50行,干干净净的解决了问题,越来越觉得他真的好厉害。。。)

(学习的越多越觉得他棒棒。突然觉得我得好好努力,不然连大佬有多厉害都不知道)

#include <iostream>
#include <string.h>
using namespace std;
int c[1000000];

void multip(char a[],char b[],int alen,int blen) 
{
	int i=0,j=0,k=0;
	for(i=alen-1;i>=0;i--)
	{
		for(j=blen-1;j>=0;j--)
		{
			c[alen-1-i+blen-1-j]+=(a[i]-'0')*(b[j]-'0');
		}
	}
	
	for(k=0;k<alen+blen;k++)
	{
		c[k+1]=c[k+1]+c[k]/10;
		c[k]=c[k]%10;
	}
	
	while(c[k]==0)
	{
		k--;
	}

	for(i=k;i>=0;i--)
	{
		cout<<c[i];
	}	
 } 

int main()
{
	char a[500];
    char b[500]; 
	cin>>a>>b;
	
	int alen=0,blen=0;
	alen=strlen(a);
	blen=strlen(b);
	
	multip(a,b,alen,blen);
		
	return 0;
}

原来Kevin真的有每天看我这种小弱鸡的博客。。。

突然紧脏。。。

 

怪不得昨晚梦见慌慌乱乱的参加考试。。。

                        

加油内~

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值