1. 程式人生 > >7屆藍橋杯第10題 -壓縮變換

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 ,根本就是不讓你使用演算法策略的意思