1. 程式人生 > >藍橋杯2016年第7屆省賽

藍橋杯2016年第7屆省賽

結果填空

煤球數目

有一堆煤球,堆成三角稜錐形。具體:
第一層放1個,
第二層3個(排列成三角形),
第三層6個(排列成三角形),
第四層10個(排列成三角形),
….
如果一共有100層,共有多少個煤球? 171700

public class Main {
    public static void main(String[] args) {
        int a = 1;
        int sum = a;
        for (int i = 2; i <= 100; i++) {
            a += i;
            sum += a;
        }
        System.out.println(sum);
    }
}

生日蠟燭

某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。

現在算起來,他一共吹熄了236根蠟燭。

請問,他從多少歲開始過生日party的? 26

public class Main {
    public static void main(String[] args) {
        int start = 1;
        int end = 2;
        while (true) {
            int sum = (start + end) * (end - start + 1) / 2;
            if
(sum < 236) { end++; } else if (sum > 236) { start++; } else { System.out.println(start); break; } } } }

湊算式

湊算式

這個算式中A~I代表1~9的數字,不同的字母代表不同的數字。

比如:
6+8/3+952/714 就是一種解法,
5+3/1+972/486 是另一種解法。

這個算式一共有多少種解法? 29

public class Main {
    static int solution = 0;
    static int[] number = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    public static void main(String[] args) {
        backTrack(0);
        System.out.println(solution);
    }

    static void backTrack(int depth) {
        if (depth == 9) {
            if (isOK()) {
                solution++;
            }
        } else {
            for (int i = depth; i < 9; i++) {
                swap(number, depth, i);
                backTrack(depth + 1);
                swap(number, depth, i);
            }
        }
    }

    static boolean isOK() {
        int A = number[0];
        int B = number[1];
        int C = number[2];
        int DEF = number[3] * 100 + number[4] * 10 + number[5];
        int GHI = number[6] * 100 + number[7] * 10 + number[8];
        return GHI * B + DEF * C == (10 - A) * C * GHI;
    }

    static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
}

網友年齡

某君新認識一網友。
當問及年齡時,他的網友說:
“我的年齡是個2位數,我比兒子大27歲,
如果把我的年齡的兩位數字交換位置,剛好就是我兒子的年齡”

請你計算:網友的年齡一共有多少種可能情況? 7

提示:30歲就是其中一種可能哦.

public class Main {
    public static void main(String[] args) {
        int maybe = 0;
        for (int mom = 28; mom <= 99; mom++) {
            for (int son = 1; son <= mom - 27; son++) {
                int a = mom / 10;
                int b = mom % 10;
                int c = b * 10 + a;
                if (c == son && mom - 27 == son) {
                    maybe++;
                }
            }
        }
        System.out.println(maybe);
    }
}

平方怪圈

如果把一個正整數的每一位都平方後再求和,得到一個新的正整數。
對新產生的正整數再做同樣的處理。

如此一來,你會發現,不管開始取的是什麼數字,
最終如果不是落入1,就是落入同一個迴圈圈。

請寫出這個迴圈圈中最大的那個數字。 145

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<Integer, Boolean> isPut = new HashMap<>();
        int a = 2;
        int sum = 0;
        while (true) {
            while (a != 0) {
                sum += Math.pow(a % 10, 2);
                a /= 10;
            }
            a = sum;
            sum = 0;
            // 落入迴圈即以前已經新增過
            if (isPut.get(a) != null) {
                for (Integer i : isPut.keySet()) {
                    System.out.print(i + " ");
                }
                break;
            } else {
                isPut.put(a, true);
            }
        }
    }
}

搭積木

小明最近喜歡搭數字積木,
一共有10塊積木,每個積木上有一個數字,0~9。

搭積木規則:
每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。
最後搭成4層的金字塔形,必須用完所有的積木。

下面是兩種合格的搭法:

   0
  1 2
 3 4 5
6 7 8 9

   0
  3 1
 7 5 2
9 8 6 4    

請你計算這樣的搭法一共有多少種? 768

public class Main {
    static int[] number = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    static int count = 0;

    public static void main(String[] args) {
        backTrack(0);
        System.out.println(count);
    }

    static void backTrack(int n) {
        if (n == 10) {
            count++;
        } else {
            for (int i = n; i < 10; i++) {
                swap(n, i);
                if (isOK(n)) {
                    backTrack(n + 1);
                }
                swap(n, i);
            }
        }
    }

    static void swap(int i, int j) {
        int tmp = number[i];
        number[i] = number[j];
        number[j] = tmp;
    }

    static boolean isOK(int n) {
        switch (n) {
        case 1:
            return number[0] < number[1];
        case 2:
            return number[0] < number[2];
        case 3:
            return number[1] < number[3];
        case 4:
            return number[1] < number[4] && number[2] < number[4];
        case 5:
            return number[2] < number[5];
        case 6:
            return number[3] < number[6];
        case 7:
            return number[3] < number[7] && number[4] < number[7];
        case 8:
            return number[4] < number[8] && number[5] < number[8];
        case 9:
            return number[5] < number[9];
        default:
            return true;
        }
    }
}

方格填數

如下的10個格子

方格填數

填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)

一共有多少種可能的填數方案? 1580

public class Main {
    static int solution = 0;
    static int number[] = new int[10];
    static int map[][] = new int[3][4];

    public static void main(String args[]) {
        for (int x = 0; x < 3; x++) {
            for (int y = 0; y < 4; y++) {
                // 初始化資料,(除了-1到10之間)的數都可行,這裡初始化為-2
                map[x][y] = -2;
            }
        }
        backTrack(0, 1);
        System.out.println(solution);
    }

    static void backTrack(int x, int y) {
        if (x == 2 && y == 3) {
            solution++;
        } else {
            // 將0到9都填入該方格
            for (int num = 0; num <= 9; num++) {
                if (number[num] == 1 || isContinuous(num, x, y)) {
                    continue;
                }
                map[x][y] = num;
                number[num] = 1;
                backTrack(x + (y + 1) / 4, (y + 1) % 4);
                map[x][y] = -2;
                number[num] = 0;
            }
        }
    }

    // 判斷相鄰格子的數字是否連續
    static boolean isContinuous(int num, int x, int y) {
        // 上方
        if (x >= 1 && Math.abs(map[x - 1][y] - num) == 1) {
            return true;
        }
        // 左方
        if (y >= 1 && Math.abs(map[x][y - 1] - num) == 1) {
            return true;
        }
        // 左上方
        if (x >= 1 && y >= 1 && Math.abs(map[x - 1][y - 1] - num) == 1) {
            return true;
        }
        // 右上方
        if (x >= 1 && y < 3 && Math.abs(map[x - 1][y + 1] - num) == 1) {
            return true;
        }
        // 右方
        if (y < 3 && Math.abs(map[x][y + 1] - num) == 1) {
            return true;
        }
        // 下方
        if (x < 2 && Math.abs(map[x + 1][y] - num) == 1) {
            return true;
        }
        // 左下方
        if (x < 2 && y >= 1 && Math.abs(map[x + 1][y - 1] - num) == 1) {
            return true;
        }
        // 右下方
        if (x < 1 && y < 3 && Math.abs(map[x + 1][y + 1] - num) == 1) {
            return true;
        }
        return false;
    }
}

剪郵票

如圖,有12張連在一起的12生肖的郵票。

剪郵票

現在你要從中剪下5張來,要求必須是連著的。(僅僅連線一個角不算相連)

如圖2,圖3中,粉紅色所示部分就是合格的剪取。

剪郵票

剪郵票

請你計算,一共有多少種不同的剪取方法? 116

public class Main {
    static int solution = 0;
    static int[] number = new int[5];
    static int[] isChosen = new int[12];

    public static void main(String args[]) {
        // 從12個數字裡選5個數字
        backTrack(0);
        System.out.println(solution);
    }

    static void backTrack(int n) {
        // 去重
        if (n > 1 && number[n - 1] < number[n - 2]) {
            return;
        }
        if (n == 5) {
            if (isOK()) {
                // printNumber();
                solution++;
            }
        } else {
            for (int i = 0; i < 12; i++) {
                if (isChosen[i] == 0) {
                    isChosen[i] = 1;
                    number[n] = i;
                    backTrack(n + 1);
                    isChosen[i] = 0;
                }
            }
        }
    }

    static boolean isOK() {
        boolean[] isVisit = new boolean[5];
        dfs(isVisit, 0);
        return isVisit[0] && isVisit[1] && isVisit[2] && isVisit[3] && isVisit[4];
    }

    static void dfs(boolean isVisit[], int i) {
        isVisit[i] = true;
        for (int j = 0; j < isVisit.length; j++) {
            if (!isVisit[j]) {
                if (number[i] / 4 == number[j] / 4 && Math.abs(number[i] - number[j]) == 1) {
                    dfs(isVisit, j);
                }
                if (Math.abs(number[i] - number[j]) == 4) {
                    dfs(isVisit, j);
                }
            }
        }
    }

    static void printNumber() {
        for (int i : number) {
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

寒假作業

現在小學的數學題目也不是那麼好玩的。
看看這個寒假作業:

□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □

每個方塊代表1~13中的某一個數字,但不能重複。
比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5

以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5

就算兩種解法。(加法,乘法交換律後算不同的方案)

你一共找到了多少種方案? 64

public class Main {
    static int[] number = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
    static int count = 0;

    public static void main(String[] args) {
        backTrack(0);
        System.out.println(count);
    }

    static void backTrack(int n) {
        if (n == 13) {
            System.out.println(number[0] + "+" + number[1] + "=" + number[2]);
            System.out.println(number[3] + "-" + number[4] + "=" + number[5]);
            System.out.println(number[6] + "*" + number[7] + "=" + number[8]);
            System.out.println(number[9] + "/" + number[10] + "=" + number[11]);
            System.out.println(number[9] + "/" + number[10] + "=" + number[12]);
            System.out.println();
            count++;
        } else {
            for (int i = n; i < 13; i++) {
                swap(n, i);
                if (isOK(n)) {
                    backTrack(n + 1);
                }
                swap(n, i);
            }
        }
    }

    static void swap(int i, int j) {
        int tmp = number[i];
        number[i] = number[j];
        number[j] = tmp;
    }

    static boolean isOK(int n) {
        switch (n) {
        case 2:
            return number[0] + number[1] == number[2];
        case 5:
            return number[3] - number[4] == number[5];
        case 8:
            return number[6] * number[7] == number[8];
        case 11:
            return number[11] * number[12] == number[10];
        default:
            return true;
        }
    }
}

程式碼填空

分小組

9名運動員參加比賽,需要分3組進行預賽。
有哪些分組的方案呢?

我們標記運動員為 A,B,C,… I
下面的程式列出了所有的分組方法。

該程式的正常輸出為:
ABC DEF GHI
ABC DEG FHI
ABC DEH FGI
ABC DEI FGH
ABC DFG EHI
ABC DFH EGI
ABC DFI EGH
ABC DGH EFI
ABC DGI EFH
ABC DHI EFG
ABC EFG DHI
ABC EFH DGI
ABC EFI DGH
ABC EGH DFI
ABC EGI DFH
ABC EHI DFG
ABC FGH DEI
ABC FGI DEH
ABC FHI DEG
ABC GHI DEF
ABD CEF GHI
ABD CEG FHI
ABD CEH FGI
ABD CEI FGH
ABD CFG EHI
ABD CFH EGI
ABD CFI EGH
ABD CGH EFI
ABD CGI EFH
ABD CHI EFG
ABD EFG CHI
….. (以下省略,總共560行)。

public class Main {
    public static String remain(int[] a) {
        String s = "";
        for (int i = 0; i < a.length; i++) {
            if (a[i] == 0)
                s += (char) (i + 'A');
        }
        return s;
    }

    public static void f(String s, int[] a) {
        for (int i = 0; i < a.length; i++) {
            if (a[i] == 1)
                continue;
            a[i] = 1;
            for (int j = i + 1; j < a.length; j++) {
                if (a[j] == 1)
                    continue;
                a[j] = 1;
                for (int k = j + 1; k < a.length; k++) {
                    if (a[k] == 1)
                        continue;
                    a[k] = 1;
                    // System.out.println(_____________); //填空
                    System.out.println(s + " " + (char) (i + 'A') + (char) (j + 'A') + (char) (k + 'A') + " " + remain(a));
                    a[k] = 0;
                }
                a[j] = 0;
            }
            a[i] = 0;
        }
    }

    public static void main(String[] args) {
        int[] a = new int[9];
        a[0] = 1;

        for (int b = 1; b < a.length; b++) {
            a[b] = 1;
            for (int c = b + 1; c < a.length; c++) {
                a[c] = 1;
                String s = "A" + (char) (b + 'A') + (char) (c + 'A');
                f(s, a);
                a[c] = 0;
            }
            a[b] = 0;
        }
    }
}

抽籤

X星球要派出一個5人組成的觀察團前往W星。
其中:
A國最多可以派出4人。
B國最多可以派出2人。
C國最多可以派出2人。
….

那麼最終派往W星的觀察團會有多少種國別的不同組合呢?

下面的程式解決了這個問題。
陣列a[]中是每個國家可以派出的最多的名額。
程式執行結果為:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
….
(以下省略,總共101行)

public class Main {
    public static void f(int[] a, int k, int n, String s) {
        if (k == a.length) {
            if (n == 0)
                System.out.println(s);
            return;
        }

        String s2 = s;
        for (int i = 0; i <= a[k]; i++) {
            // _____________________________; //填空位置
            // a:各個國家能派的人數
            // k:第幾個國家
            // n:還需要派幾個人
            // s2:當前派遣隊伍
            f(a, k + 1, n - i, s2);
            s2 += (char) (k + 'A');
        }
    }

    public static void main(String[] args) {
        int[] a = { 4, 2, 2, 1, 1, 3 };
        f(a, 0, 5, "");
    }
}

消除尾一

下面的程式碼把一個整數的二進位制表示的最右邊的連續的1全部變成0
如果最後一位是0,則原數字保持不變。

如果採用程式碼中的測試資料,應該輸出:
00000000000000000000000001100111 00000000000000000000000001100000
00000000000000000000000000001100 00000000000000000000000000001100

請仔細閱讀程式,填寫劃線部分缺少的程式碼。

public class Main {
    public static void main(String[] args) {
        f(103);
        f(12);
    }

    private static void f(int x) {
        int i;
        for (i = 0; i < 32; i++)
            System.out.print(x >> (31 - i) & 1);
        System.out.print("   ");

        // x = _______________________; // 填空
        x = x & (x + 1);

        for (i = 0; i < 32; i++)
            System.out.print(x >> (31 - i) & 1);
        System.out.println();
    }
}

快速排序

排序在各種場合經常被用到。
快速排序是十分常用的高效率的演算法。

其思想是:先選一個“標尺”,用它把整個佇列過一遍篩子,以保證:其左邊的元素都不大於它,其右邊的元素都不小於它。

這樣,排序問題就被分割為兩個子區間。
再分別對子區間排序就可以了。

下面的程式碼是一種實現,請分析並填寫劃線部分缺少的程式碼。

public class Main {
    public static void main(String[] args) {
        int i;
        int a[] = { 5, 13, 6, 24, 2, 8, 19, 27, 6, 12, 1, 17 };
        int N = 12;

        quicksort(a, 0, N - 1);

        for (i = 0; i < N; i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    private static int partition(int[] a, int p, int r) {
        int i = p;
        int j = r + 1;
        int x = a[p];
        while (true) {
            while (i < r && a[++i] < x)
                ;
            while (a[--j] > x)
                ;
            if (i >= j)
                break;
            swap(a, i, j);
        }
        // ______________________; // 填空
        swap(a, p, j);
        return j;
    }

    private static void quicksort(int[] a, int p, int r) {
        if (p < r) {
            int q = partition(a, p, r);
            quicksort(a, p, q - 1);
            quicksort(a, q + 1, r);
        }
    }

    private static void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
}

骰子游戲

我們來玩一個遊戲。
同時擲出3個普通骰子(6個面上的數字分別是1~6)。
如果其中一個骰子上的數字等於另外兩個的和,你就贏了。

下面的程式計算出你能獲勝的精確概率(以既約分數表示)

public class Main {
    public static void main(String[] args) {
        int n = 0;
        for (int i = 0; i < 6; i++)
            for (int j = 0; j < 6; j++)
                for (int k = 0; k < 6; k++) {
                    // if(________________________________) n++; //填空位置
                    if ((i + 1) + (j + 1) == (k + 1)
                        || (i + 1) + (k + 1) == (j + 1)
                        || (j + 1) + (k + 1) == (i + 1))
                        n++;
                }

        int m = gcd(n, 6 * 6 * 6);
        System.out.println(n / m + "/" + 6 * 6 * 6 / m);
    }

    public static int gcd(int a, int b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
}

程式設計

四平方和

四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多4個正整數的平方和。
如果把0包括進去,就正好可以表示為4個數的平方和。

比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符號表示乘方的意思)

對於一個給定的正整數,可能存在多種平方和的表示法。
要求你對4個數排序:
0 <= a <= b <= c <= d
並對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最後輸出第一個表示法

程式輸入為一個正整數N (N<5000000)
要求輸出4個非負整數,按從小到大排序,中間用空格分開

樣例輸入1:
5
樣例輸出1:
0 0 1 2

樣例輸入2:
12
樣例輸出2:
0 2 2 2

樣例輸入3:
773535
樣例輸出4:
1 1 267 838

資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗 < 3000ms

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {
    static Scanner scanner = new Scanner(new BufferedInputStream(System.in));

    public static void main(String args[]) {
        int n = scanner.nextInt();
        for (int a = 0; a < Math.sqrt(n); a++) {
            for (int b = a; b < Math.sqrt(n); b++) {
                for (int c = b; c < Math.sqrt(n); c++) {
                    for (int d = c; d < Math.sqrt(n); d++) {
                        if (a * a + b * b + c * c + d * d == n) {
                            System.out.printf("%d %d %d %d", a, b, c, d);
                            return;
                        }
                    }
                }
            }
        }
    }
}

取球博弈

兩個人玩取球的遊戲。
一共有N個球,每人輪流取球,每次可取集合{n1,n2,n3}中的任何一個數目。
如果無法繼續取球,則遊戲結束。
此時,持有奇數個球的一方獲勝。
如果兩人都是奇數,則為平局。

假設雙方都採用最聰明的取法,
第一個取球的人一定能贏嗎?
試程式設計解決這個問題。

輸入格式:
第一行3個正整數n1 n2 n3,空格分開,表示每次可取的數目 (0

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {
    static Scanner scanner = new Scanner(new BufferedInputStream(System.in));
    static int[] ball = new int[3];
    static int[] init = new int[5];
    static String result = "";

    public static void main(String args[]) {
        for (int i = 0; i < 3; i++) {
            ball[i] = scanner.nextInt();
        }
        for (int i = 0; i < 5; i++) {
            init[i] = scanner.nextInt();
        }
        play();
        System.out.println(result.toString());
    }

    // 還可以取的球數
    static int rest = 0;
    static int first = 0, second = 0;

    static void play() {
        for (int i = 0; i < 5; i++, first = 0, second = 0) {
            rest = init[i];
            while (rest > 0) {
                first += afterPick(first);
                second += afterPick(second);
            }
            judge();
        }
    }

    static int afterPick(int self) {
        int pick = -1;
        // 奇 + 奇 = 偶
        // 偶 + 偶 = 偶
        // 持有奇數個球
        if ((self & 1) == 1) {
            // 找到最大偶數,保證取到後仍是最大奇數
            for (int i = 2; i >= 0; i--) {
                if ((ball[i] & 1) == 0) {
                    if (rest >= ball[i]) {
                        rest -= ball[i];
                        pick = ball[i];
                        break;
                    }
                }
            }
        } else {
            // 找到最大奇數
            for (int i = 2; i >= 0; i--) {
                if ((ball[i] & 1) == 1) {
                    if (rest >= ball[i]) {
                        rest -= ball[i];
                        pick = ball[i];
                        break;
                    }
                }
            }
        }
        // 找不到
        if (pick == -1) {
            for (int i = 2; i >= 0; i--) {
                if (rest >= ball[i]) {
                    rest -= ball[i];
                    pick = ball[i];
                    break;
                }
                // 如果到最小球還沒找到,即剩餘的比最小球還小
                // 一般來說到了最後一個,預設兩者都不取球
                if (i == 0 && pick == -1) {
                    rest = 0;
                    pick = 0;
                }
            }
        }
        return pick;
    }

    static void judge() {
        if ((first & 1) == 1) {
            if ((second & 1) == 1) {
                result += "0";
            } else {
                result += "+";
            }
        } else {
            if ((second & 1) == 0) {
                result += "0";
            } else {
                result += "-";
            }
        }
        result += " ";
    }
}

壓縮變換

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

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

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

比如,序列(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個數,表示變換後的序列。

樣例輸入1:
5
1 2 2 1 2

樣例輸出1:
-1 -2 0 1 1

樣例輸入2:
12
1 1 2 3 2 3 1 2 2 2 3 1

樣例輸出2:
-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

import java.util.HashMap;
import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {
    static Scanner scanner = new Scanner(new BufferedInputStream(System.in));
    static int n = scanner.nextInt();
    static int[] sequence = new int[n];
    static int[] newSequence = new int[n];

    public static void main(String args[]) {
        for (int i = 0; i < n; i++) {
            sequence[i] = scanner.nextInt();
        }
        // 字典
        // key:序列數字
        // value:從前一次出現到當前出現間,不同的數字
        HashMap<Integer, HashMap<Integer, Integer>> type = new HashMap<>();
        for (int i = 0, k = 0; i < n; i++) {