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是給那些不知道如何下手的同學一個參考
		

雖然這道題很麻煩!但是隻要細心也是能夠做出來的。
不要找藉口,要用於挑戰自己!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章