1. 程式人生 > >小朋友排隊--第五屆藍橋杯

小朋友排隊--第五屆藍橋杯

code als ann 沒有 clas art 相對 pri rgs

第一種,直接思考的方法,不知對不正確:

/*
 * 標題:小朋友排隊
 n 個小朋友站成一排。如今要把他們按身高從低到高的順序排列,可是每次僅僅能交換位置相鄰的兩個小朋友。

每一個小朋友都有一個不高興的程度。

開始的時候。全部小朋友的不高興程度都是0。 假設某個小朋友第一次被要求交換,則他的不高興程度添加1,假設第二次要求他交換。 則他的不高興程度添加2(即總的不高興程度為3)。依次類推。

當要求某個小朋友第k次交換時,他的不高興程度添加k。 請問。要讓全部小朋友按從低到高排隊。他們的不高興程度之和最小是多少。 假設有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關系的。 【數據格式】 輸入的第一行包括一個整數n,表示小朋友的個數。 第二行包括 n 個整數 H1 H2 … Hn,分別表示每一個小朋友的身高。 輸出一行,包括一個整數,表示小朋友的不高興程度和的最小值。 比如,輸入: 3 3 2 1 程序應該輸出: 9 【例子說明】 首先交換身高為3和2的小朋友,再交換身高為3和1的小朋友,再交換身高為2和1的小朋友,每一個小朋友的不高興程度都是3。總和為9。 【數據規模與約定】 對於10%的數據, 1<=n<=10; 對於30%的數據, 1<=n<=1000。 對於50%的數據。 1<=n<=10000; 對於100%的數據,1<=n<=100000,0<=Hi<=1000000。 資源約定: 峰值內存消耗 < 256M CPU消耗 < 1000ms */ public class 小朋友排隊 { static int n; static int[] s;// 每一個小朋友的身高 static int bugaoxing = 99999;// 不高興的值總和 /** * 當前最高興的小朋友的值總的高興值 */ public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); s = new int[n]; int[][] count = new int[n][2]; for (int i = 0; i < n; i++) { s[i] = sc.nextInt(); count[i][0] = 0; count[i][1] = 0; } long start = System.currentTimeMillis(); int all = exchange(findMin(count), count); print("不高興的總和數量是=" + all); long end = System.currentTimeMillis(); print("此程序執行,花費的時間是" + ((end - start) / 1000.0) + "秒."); print("每一個小朋友不高興的詳情信息"); for (int i = 0; i < n; i++) { print(i + "不高興的值是=" + count[i][0]); } } /** * 交換位置,身高高的向右和身高低的能夠換,否則下一個相鄰位置 * * @param k * 前搜索的位置 * @param count * count[0][]當前每一個交換的小朋友的不高興程度和count[1][]交換的次數 */ public static int exchange(int k, int[][] count) { if (isOk()) { int temp = sum(count); if (temp < bugaoxing) bugaoxing = temp; return temp; } else { /** 交換身高,從最不高興的到最高興的意思搜索 */ exchangeAll(count, k); System.out.println("K&k+1=" + k + " " + (k + 1)); return exchange(findMin(count), count); } } /** * * @return 返回當前相對最高興的小朋友的下標值,(同事滿足身高左高右低的要求) */ public static int findMin(int[][] count) { int[] temp = new int[n]; for (int i = 0; i < n; i++) { temp[i] = count[i][1]; } for (int i = 0; i < n; i++) { int min = i; for (int j = i + 1; j < n; j++) { if (temp[min] > temp[j]) min = j; } temp[min] = temp[i]; if (min < n - 1 && s[min] > s[min + 1]) return min; } return n - 2; } /** * 交換位置和不高興的值下標k和k+1的交換,同一時候不高興的值添加 * * @return */ public static void exchangeAll(int[][] count, int k) { int temp; temp = s[k + 1]; s[k + 1] = s[k]; s[k] = temp; count[k][1]++; count[k][0] = count[k][0] + count[k][1]; count[k + 1][1]++; count[k + 1][0] = count[k + 1][0] + count[k + 1][1]; int[] temp1 = count[k]; count[k] = count[k + 1]; count[k + 1] = temp1; } public static boolean isOk() {// 是否排好序 for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (s[j] < s[i]) return false; } } return true; } // 當前全部人不高興的值的總和 public static int sum(int[][] count) { int temp = 0; for (int i = 0; i < n; i++) temp += count[i][0]; return temp; } public static void print(Object o) { System.out.println(o.toString()); } }



輸入和輸出一:

3
3 2 1
K&k+1=0 1
K&k+1=1 2
K&k+1=0 1
不高興的總和數量是=9
每一個小朋友不高興的詳情信息
0不高興的值是=3
1不高興的值是=3
2不高興的值是=3
此程序執行,花費的時間是0.0秒.

輸入和輸出二:

5
5 4 3 2 1
K&k+1=0 1
K&k+1=2 3
K&k+1=1 2
K&k+1=3 4
K&k+1=0 1
K&k+1=2 3
K&k+1=1 2
K&k+1=3 4
K&k+1=0 1
K&k+1=2 3
不高興的總和數量是=50
每一個小朋友不高興的詳情信息
0不高興的值是=10
1不高興的值是=10
2不高興的值是=10
3不高興的值是=10
4不高興的值是=10
此程序執行,花費的時間是0.001秒.


輸入和輸出三:

5
2 5 4 3 1
K&k+1=1 2
K&k+1=3 4
K&k+1=2 3
K&k+1=1 2
K&k+1=0 1
K&k+1=3 4
K&k+1=2 3
不高興的總和數量是=29
此程序執行,花費的時間是0.0秒.
每一個小朋友不高興的詳情信息
0不高興的值是=10
1不高興的值是=1
2不高興的值是=6
3不高興的值是=6
4不高興的值是=6


小朋友排隊--第五屆藍橋杯