HDU 2020绝对值排序!!!

									绝对值排序

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 136025 Accepted Submission(s): 64004

Problem Description
输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。

Input
输入数据有多组,每组占一行,每行的第一个数字为n,接着是n个整数,n=0表示输入数据的结束,不做处理。

Output
对于每个测试实例,输出排序后的结果,两个数之间用一个空格隔开。每个测试实例占一行。

Sample Input
3 3 -4 2
4 0 1 2 -3
0

Sample Output
-4 3 2
-3 2 1 0

这道题我觉得很麻烦!但是我嚼劲脑汁终于自己做出来啦!我没有百度或者用别人的方法。我全部是自己想的,所以这篇博客我只想记录一下我AC这道题的过程和自己的思考过程!
我觉得对我自己来说太有成就感啦!
当然你也可以作为参考

绝对值排序思路:
利用三个数组a,b,c。a数组记录原来的值,b数组记录绝对值的值
两个数组,两种实现方法,将b数组排序后输出a,但问题是b排序后b数组里的值会改变,b的下标顺序将被打乱
在这种情况下:
有两条路可以走
1,将b数组的小标保存在另一个数组里,将b组最大数的小标放在c数组的第一位,依次进行,最后将c组里的值(即b组元素的下标)当做a数组的值依次输出,do you unsterstand?
我想你应该明白的

2,依次找出b组的最大值,找到该最大值后把最大值置为空(目的是下次在b组找次大值得时候跳过)但是如何将b值得最大值作为标记以防止下次被遍历到呢?
同样创建c数组,开始全部置为0,每次对b组数据进行循环找出最大值后将此位置对应的c数组置为-1,接着下次将c数组作为遍历条件,跳过上次循环的最大值位置,循环找出的次大值,这样依次进行。
不断的找出最大值,然后将最大值的下标给a数组然后进行输出!

这是两种思路!我采用的是第二种思路
好啦!有些东西说的不太清楚,来看代码
在这里插入图片描述
时间是0ms我觉得还行!

下面通过注释来进行讲解一下
可能不是很美观!但我的目的不是让你复制我的代码然后AC掉,那又有什么意义呢?
我是让你看懂我的代码结合我讲的思路然后自行写代码,这样才会有大大的收获的!
Come on!

#include<iostream>
#include<math.h>
using namespace std;
int main()
{
	int n;
	while(cin>>n&&n)
	{
		int a[101];
		int b[101];
		int c[101]={0};//c数组全部为0
		int i=0,j=0;
		int temp;
		int num=n;//num作为数组的长度,切记不要用n,因为n会变为0的
		while(n--)
		{
			cin>>temp;
			a[i++]=temp;
			b[j++]=(int)abs(temp);
		}
		//a是原数组,b数将a数组里的元素取绝对值后的数组
		i=0;j=0;
		int k;
		int count=0;//用来计数(1是为了控制末尾的格式,2是方便跳出外层循环)
		int max;
		for(i=0;i<num;i++)
		{
			if(c[i]==-1)// 重点,如果没这句话,测试用例1是无法通过的
				continue;
			max=b[i];//先将b数组的首位赋给最大(因为存在首位一开始就会最大值得情况,故将此时的i值赋给k)
			k=i;
			for(j=0;j<num;j++)//进入循环,在b数组找最大值
			{
				if(b[j]>max&&c[j]!=-1)//如果这个最大已经找到啦,用c[j]作为标记表示这轮循环不要用他比较
				{
					max=b[j];
					k=j;
				}
			}
			count++;//每次找到一个最大值+1
			c[k]=-1;//找到最大值的位置时c数组置为-1
			if(k!=i)
				i--;//如果该轮循环最大值不是首位的情况,i减1,下次还是将b组首位给最大值max
				//如果首位是最大值i则不需减1(此时首位的c数组为-1,所以给首位的时候有一个判断,)将b的下一位作为最大值进行比较,
			if(count!=num)
				cout<<a[k]<<" ";
			if(count==num)
			{
				cout<<a[k]<<endl;
				break;//因为不是用i作为跳出循环的,因为有时候i是没有移动的,所以如果输出的次数刚好为数组长度也是照常跳出的
			}
		}
			
	}
	return 0;
}
		
//代码可能比较长,但是理清楚几个点就可以啦!你可以先按我的思路来写代码,
//后面有错误可以慢慢改当然也可以参考我的代码

//我既然写这篇博客,1*是为了纪念我胜利的时刻,开心,哈哈哈*,2是给那些不知道如何下手的同学一个参考
		

虽然这道题很麻烦!但是只要细心也是能够做出来的。
不要找借口,要用于挑战自己!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值