《编程思维与实践》1073.遥远距离

《编程思维与实践》1073.遥远距离

题目在这里插入图片描述

思路

先从小到大排序,再复用大整数的处理方式将最大的数减去最小的数即可.

注意的点:

数据可能出现负整数,需要补充符号.

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define N 121

typedef struct{int cnt,v[N],sign;}BIGINT;

BIGINT carry(BIGINT S,int bin);   //进位 bin表示进制 binary
BIGINT add(BIGINT S, BIGINT T,int sign);     //两个大整数相加
BIGINT sub(BIGINT S, BIGINT T,int sign);     //两个大整数相减 两个大整数均非负
int cmp(const void *a,const void *b);  //从小到大 

int main()
{
	int n;
	scanf("%d",&n);
	BIGINT tab[n]; 
	for(int i=0;i<n;i++)
	{
		tab[i].sign=1;
		tab[i].cnt=0;
		memset(tab[i].v,0,sizeof(tab[i].v));  //初始化
		char s[121];
		scanf("%s",s);
		int j;
		for(j=strlen(s)-1;j>=0&&isdigit(s[j]);j--)  //逆序存
		{
			tab[i].v[tab[i].cnt++]=s[j]-'0';
		}
		if(j==0)
		{
			tab[i].sign=-1;
		}
	}
	qsort(tab,n,sizeof(BIGINT),cmp);
	BIGINT ans=sub(tab[n-1],tab[0],0);
	for(int i=ans.cnt-1;i>=0;i--)
	{
		printf("%d",ans.v[i]);
	}
	return 0;
} 

int cmp(const void *a,const void *b)  //从小到大 
{
	BIGINT *m=(BIGINT*)a;
	BIGINT *n=(BIGINT*)b;
	if(m->sign!=n->sign)
	{
		return m->sign==1?1:-1;
	}
	else if(m->sign==n->sign)   //符号相同
	{
		if(m->cnt<n->cnt)
		{
		    return -1*m->sign;  //如果均为负号 返回值相反
		}
	    else if(m->cnt==n->cnt)  
	    {
	        for(int i=m->cnt-1;i>=0;i--)   //注意是从最高位开始比 
	        {
	            if(n->v[i]<m->v[i])
	            {
	                return 1*m->sign;
	            }
	            else if(n->v[i]>m->v[i])
	            {
	                return -1*m->sign;
	            }
	        }
	    }
	}
}

BIGINT carry(BIGINT S,int bin)   //进位 bin表示进制 binary
{
	int flag=0;
	for(int i=0;i<S.cnt;i++)
	{
		int temp=S.v[i]+flag;
		S.v[i]=temp%bin;
		flag=temp/bin;
	}
	if(flag)
	{
		S.v[S.cnt++]=flag;
	}
	return S;
}

BIGINT add(BIGINT S, BIGINT T,int sign)     //两个大整数相加
{
	if(sign==0)
	{
		if(S.sign==-1&&T.sign==-1)
		{
			sign=-1;
		}
		else if(S.sign==1&&T.sign==-1)
		{
			return sub(S,T,1);
		} 
		else if(S.sign==-1&&T.sign==1)
		{
			return sub(T,S,1);
		}
		else
		{
			sign=1;
		}
	}
	int max=S.cnt>T.cnt?S.cnt:T.cnt;
	BIGINT R={max,{0},sign};
	for(int i=0;i<max;i++)
	{
		R.v[i]=S.v[i]+T.v[i];   //依次进行普通乘法
	}
	R=carry(R,10);
	for(int i=R.cnt-1;i>=1&&R.v[i]==0;i--)  //去前置0(本题0的位数记为1) 
    {
        R.cnt--;
    }
	return R;
}

BIGINT mul(BIGINT S, BIGINT T)     //两个大整数相乘
{
    BIGINT R={S.cnt+T.cnt,{0},S.sign*T.sign};  //位数最多为两者相加
    for(int i=0;i<T.cnt;i++)
    {
        for (int j=0;j<S.cnt;j++)
        {
            R.v[i+j]+=S.v[j]*T.v[i];   //依此进行普通乘法
        }
    }
    R=carry(R,10);
    if(R.v[S.cnt+T.cnt-1]==0) 
	{
		R.cnt--; //最高位0不统计在一个大整数的位数中
	}
    return R;
}

BIGINT sub(BIGINT S, BIGINT T,int sign)     //两个大整数相减 两个大整数均非负
{
	if(sign==0)
	{
		if(S.sign==-1&&T.sign==1)
		{
			return add(S,T,-1);
		}
		else if(S.sign==-1&&T.sign==-1)
		{
			return sub(T,S,1);
		}
		else if(S.sign==1&&T.sign==-1)
		{
			return add(S,T,1);
		}
		else
		{
			sign=1;
		}
	}
	BIGINT R={S.cnt,{0},sign};
	int flag=0;  //借位
	for(int i=0;i<R.cnt;i++)
	{
		if(S.v[i]-flag-T.v[i]>=0)
        {
            R.v[i]=S.v[i]-T.v[i]-flag;
            flag=0;
        }
        else
        {
            R.v[i]=S.v[i]-T.v[i]-flag+10;
            flag=1;
        }
	}
	for(int i=R.cnt-1;i>=1&&R.v[i]==0;i--) //去前置0(本题0的位数记为1) 
    {
        R.cnt--;
    }
	return R;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值