蓝桥杯第七届省赛JAVA真题----压缩变换
生活随笔
收集整理的這篇文章主要介紹了
蓝桥杯第七届省赛JAVA真题----压缩变换
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
壓縮變換
小明最近在研究壓縮算法。
他知道,壓縮的時候如果能夠使得數值很小,就能通過熵編碼得到較高的壓縮比。
然而,要使數值很小是一個挑戰。
最近,小明需要壓縮一些正整數的序列,這些序列的特點是,后面出現的數字很大可能是剛出現過不久的數字。對于這種特殊的序列,小明準備對序列做一個變換來減小數字的值。
變換的過程如下:
從左到右枚舉序列,每枚舉到一個數字,如果這個數字沒有出現過,剛將數字變換成它的相反數,如果數字出現過,則看它在原序列中最后的一次出現后面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。
比如,序列(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及以上版本的特性。
小明最近在研究壓縮算法。
他知道,壓縮的時候如果能夠使得數值很小,就能通過熵編碼得到較高的壓縮比。
然而,要使數值很小是一個挑戰。
最近,小明需要壓縮一些正整數的序列,這些序列的特點是,后面出現的數字很大可能是剛出現過不久的數字。對于這種特殊的序列,小明準備對序列做一個變換來減小數字的值。
變換的過程如下:
從左到右枚舉序列,每枚舉到一個數字,如果這個數字沒有出現過,剛將數字變換成它的相反數,如果數字出現過,則看它在原序列中最后的一次出現后面(且在當前數前面)出現了幾種數字,用這個種類數替換原來的數字。
比如,序列(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,否則按無效代碼處理。
理解:藍橋杯的題干長而復雜,要完全理解其中的意思貌似需要花些功夫,但其實我們不需要完全理解,只要從中梳理出解題的思路就可以了。這個題目簡單來說就是給定一串數,對于其中的每個數x,如果x在它前面一系列數字中沒有出現過,那么x變成-x;反之,如果出現了,那么找到最近一次出現的位置b,在 [b--x] 之間統計出現了幾個不同的數字,將x變成這個值。
思路1:當看到這個題目出現統計出現次數時,我首先想到用java中的Set,但是不巧的是這需要多次進行遍歷,嵌套了四層循環之后,雖然實現了代碼,當上當數據到50%左右時,就爆了。當然set也可以使用記憶化,將串中的所有數字在它之前出現的位置記錄。(不過由于set不能得到最近一次的位置,所以記憶化不太好實現)。
思路2:之后參考了網上的代碼,用Map做的,這是第一次感受到Map的魅力,原來還能這么做,利用Map的put()方法會不斷更新一個鍵的值為最新的(一個鍵只能有一個值),這剛好可以用來某個數找到最近一次出現的位置,實現了記憶化。
完整代碼如下:
Set結構:
import java.util.HashSet; import java.util.Scanner; import java.util.Set;public class Main {static int[] a, b;static int n;public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();a = new int[n + 1];b = new int[n + 1];for (int i = 0; i < a.length-1; i++) {a[i] = in.nextInt();if (i == 0) {b[i] = -1 * a[i];}}Set<Integer> set = new HashSet<Integer>();for (int i = 1; i < a.length; i++) {set.clear();for (int j = 0; j < i; j++) {set.add(a[j]);}if (!set.contains(a[i])) {b[i] = -1 * a[i];} else {for (int k = i-1; k >= 0; k--) {if (a[k] == a[i]) {set.clear();for (int l = k+1; l < i; l++) {set.add(a[l]);}break;}}b[i] = set.size();}}for (int i = 0; i < b.length-2; i++) {System.out.print(b[i] + " ");}System.out.print(b[b.length-2]);}}Map結構:
import java.util.HashMap; import java.util.Map; import java.util.Scanner;public class Main { static int[] a, b;static int n;static boolean[] flag;public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();a = new int[n + 1];b = new int[n + 1];flag = new boolean[n + 1];for (int i = 0; i < a.length-1; i++) {a[i] = in.nextInt();if (i == 0) {b[i] = -1 * a[i];}}Map<Integer, Integer> map = new HashMap<Integer, Integer>();for (int i = 1; i < a.length; i++) {if (!map.containsKey(a[i])) {b[i] = -a[i];map.put(a[i], i);flag[i] = true;} else {int last = map.get(a[i]);b[i] = cnt(last+1, i);flag[last] = false;map.put(a[i], i);flag[i] = true;}}for (int i = 0; i < b.length-2; i++) {System.out.print(b[i] + " ");}System.out.print(b[b.length-2]);}private static int cnt(int l, int r) {// TODO Auto-generated method stubint sum = 0;for (int i = l; i < r; i++) {if (flag[i] == true) {sum++;}}return sum;} }總結
以上是生活随笔為你收集整理的蓝桥杯第七届省赛JAVA真题----压缩变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python3 set相关操作
- 下一篇: Hexo+GitHub 快速搭建个人博客