7屆藍橋杯第10題 -壓縮變換

壓縮變換

小明最近在研究壓縮算法。
他知道,壓縮的時候如果能夠使得數值很小,就能通過熵編碼得到較高的壓縮比。
然而,要使數值很小是一個挑戰。

最近,小明需要壓縮一些正整數的序列,這些序列的特點是,後面出現的數字很大可能是剛出現過不久的數字。對於這種特殊的序列,小明準備對序列做一個變換來減小數字的值。

變換的過程如下:
從左到右枚舉序列,每枚舉到一個數字,如果這個數字沒有出現過,剛將數字變換成它的相反數,如果數字出現過,則看它在原序列中最後的一次出現後面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。

比如,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在變換過程爲:
a1: 1未出現過,所以a1變爲-1;
a2: 2未出現過,所以a2變爲-2;
a3: 2出現過,最後一次爲原序列的a2,在a2後、a3前有0種數字,所以a3變爲0;
a4: 1出現過,最後一次爲原序列的a1,在a1後、a4前有1種數字,所以a4變爲1;
a5: 2出現過,最後一次爲原序列的a3,在a3後、a5前有1種數字,所以a5變爲1。
現在,給出原序列,請問,按這種變換規則變換後的序列是什麼。

輸入格式:
輸入第一行包含一個整數n,表示序列的長度。
第二行包含n個正整數,表示輸入序列。

輸出格式:
輸出一行,包含n個數,表示變換後的序列。

例如,輸入:
5
1 2 2 1 2

程序應該輸出:
-1 -2 0 1 1

再例如,輸入:
12
1 1 2 3 2 3 1 2 2 2 3 1

程序應該輸出:
-1 0 -2 -3 1 1 2 2 0 0 2 2

數據規模與約定
對於30%的數據,n<=1000;
對於50%的數據,n<=30000;
對於100%的數據,1 <=n<=100000,1<=ai<=10^9


資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗  < 3000ms


請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。

所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。

這道題依然可以使用倆種方式來寫,一種是遞歸類算法策略, 一種是內嵌循環,但注意題幹中這麼一句話:”對於100%的數據,1 <=n<=100000,1<=ai<=10^9“, 顯然如果使用遞歸類算法策略來寫,肯定是極大耗時的,所以藉着遞歸的思想來轉換寫成循環

package LanQiao_TrueQuestion;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

public class lq_7_10 {
    static int n=12;
    static int[] x={1 ,1 ,2, 3, 2, 3, 1, 2, 2, 2 ,3, 1};//用戶輸入數組
    static LinkedList<Integer> newx ;//作爲新數組輸出
    static int[] y;//作爲二表存儲
    public static void main(String[] args) {
        y=new int[n];
        newx= new LinkedList<>();
       for (int i=0;i<x.length;i++){
           //遍歷y,如果數組y中存儲了相應的值,那麼遍歷區間存在多少種不同的數, 實現存儲
           for (int j = 0; j <y.length ; j++) {
               if(x[i]==y[j]){
                   Set<Integer> set=new HashSet<>();
                   for (int k = j+1; k <i ; k++) {
                        set.add(x[k]);
                   }
                   newx.addLast(set.size());
                   //修改y中存儲值
                   y[j]=0;//舊值刪除
                   y[i]=x[i];//新址添加
                   break;
               }
               if(j==y.length-1){//代表了遍歷了整個數組也沒有找到,那麼做另外處理
                   //數組y中不存在x中的元素
                   newx.addLast(x[i]-x[i]*2);
                   y[i]=x[i];//添加相應的值

               }
           }
       }
       System.out.print(newx);
    }

}

總結:要想快速寫出本題,還必須在稿紙上清晰寫出算法設計邏輯,不然寫代碼會錯誤連連

注意: 藍橋杯算法設計題8-10 ,根本就是不讓你使用算法策略的意思

 

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