《编程思维与实践》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;
}