差值
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
输入一个整数数组,将它们连接起来排成一个数,找出能排出的所有数字中最大,最小的两个,输出两个数的差值。例如输入数组{1, 2},则输出9。
-
输入
- 第一行输入一个整数T,表示有T组测试数据。每组测试数据的第一行输入一个整数n(0<n<=1000),第二行输入n个整数ai(0<=ai<2^32)。 输出
- 输出最大数最小数的差值,每个输出各占一行。 样例输入
-
1 3 1 2 3
样例输出
-
198
这个题也是错了很多次,折腾了好几天才解决.........
刚开始理解错误,后来发现是大数处理,然而比较复杂...........尝试做了做,发现这个题不是想象的那么简单............
本题考查的就是数组模拟大数进行大数运算,但是重点是字符串的排序!!!!
遵守一个原则,比的不是一个字符串的长度,而是每一位大小,比较的特殊地方在于,相同的部分直接不考虑,考虑后面的,如果某个数位数较小,那么循环起来比较...........
比如
456 456653 相比,相当于比较456456 和45665 相比,至于为什么,个人也不是很清楚,但是这个发现倒是挺奇妙的............
其他的操作是字符串的相关处理,问题不大,主要是排序!!!
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn 50005
using namespace std;
int x[maxn],y[maxn],n,cnt;
struct cz
{
char s[35];//保存字符串
}tp[1005];
int cmp(cz a,cz b)
{
int i,lena=strlen(a.s),lenb=strlen(b.s);
if(lena==lenb)//长度相同的直接比
{
return strcmp(a.s,b.s)<0;
}
int len=max(lena,lenb);
for(i=0;i<len;++i)//否则就循环比较!!!非常关键!!
{
if(a.s[i%lena]<b.s[i%lenb])
{
return 1;
}
else if (a.s[i%lena]>b.s[i%lenb])
{
return 0;
}
}
return 0;
}
void change()
{
int i,j;
cnt=0;
for(i=0;i<n;++i)//求最大!!!!!!!!!!!!!!
{
int len=strlen(tp[i].s);
for(j=len-1;j>=0;--j)
{
x[cnt++]=tp[i].s[j]-'0';
}
}
cnt=0;
for(i=n-1;i>=0;--i)//求最小!!!!!!!!!!!!
{
int len=strlen(tp[i].s);
for(j=len-1;j>=0;--j)
{
y[cnt++]=tp[i].s[j]-'0';
}
}
}
void slove()
{
sort(tp,tp+n,cmp);
change();
int i;
for(i=0;i<cnt;++i)//减法运算
{
if(x[i]<y[i])
{
--x[i+1];
x[i]+=10;
}
x[i]-=y[i];
}
while(!x[i]&&i>0)//去掉前导零
{
--i;
}
for(int j=i;j>=0;--j)//输出结果
{
printf("%d",x[j]);
}
printf("\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(x,0,sizeof(x));
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%s",tp[i].s);
}
slove();
}
return 0;
}
//2016年4月6日13:22
今天才发现自己的方法是错误的,正确的排序应该是这样
//详情 http://blog.csdn.net/liuke19950717/article/details/51073998
int cmp(cz a,cz b)
{
return strcmp(strcat(a.s,b.s),strcat(b.s,a.s))<0;
}