1. 程式人生 > >CCF——學生排隊(2017-3)

CCF——學生排隊(2017-3)

 

問題描述   體育老師小明要將自己班上的學生按順序排隊。他首先讓學生按學號從小到大的順序排成一排,學號小的排在前面,然後進行多次調整。一次調整小明可能讓一位同學出隊,向前或者向後移動一段距離後再插入佇列。
  例如,下面給出了一組移動的例子,例子中學生的人數為8人。
  0)初始佇列中學生的學號依次為1, 2, 3, 4, 5, 6, 7, 8;
  1)第一次調整,命令為“3號同學向後移動2”,表示3號同學出隊,向後移動2名同學的距離,再插入到佇列中,新佇列中學生的學號依次為1, 2, 4, 5, 3, 6, 7, 8;
  2)第二次調整,命令為“8號同學向前移動3”,表示8號同學出隊,向前移動3名同學的距離,再插入到佇列中,新佇列中學生的學號依次為1, 2, 4, 5, 8, 3, 6, 7;
  3)第三次調整,命令為“3號同學向前移動2”,表示3號同學出隊,向前移動2名同學的距離,再插入到佇列中,新佇列中學生的學號依次為1, 2, 4, 3, 5, 8, 6, 7。
  小明記錄了所有調整的過程,請問,最終從前向後所有學生的學號依次是多少?
  請特別注意,上述移動過程中所涉及的號碼指的是學號,而不是在隊伍中的位置。在向後移動時,移動的距離不超過對應同學後面的人數,如果向後移動的距離正好等於對應同學後面的人數則該同學會移動到佇列的最後面。在向前移動時,移動的距離不超過對應同學前面的人數,如果向前移動的距離正好等於對應同學前面的人數則該同學會移動到佇列的最前面。 輸入格式   輸入的第一行包含一個整數 n
,表示學生的數量,學生的學號由1到 n編號。
  第二行包含一個整數 m,表示調整的次數。
  接下來m行,每行兩個整數p, q,如果q為正,表示學號為p的同學向後移動q,如果q為負,表示學號為p的同學向前移動-q。 輸出格式   輸出一行,包含n個整數,相鄰兩個整數之間由一個空格分隔,表示最終從前向後所有學生的學號。 樣例輸入 8
3
3 2
8 -3
3 -2 樣例輸出 1 2 4 3 5 8 6 7 評測用例規模與約定   對於所有評測用例,1 ≤  n
 ≤ 1000,1 ≤  m ≤ 1000,所有移動均合法。

說明:首先判斷此人是前移還是後移,然後將此人的學號臨時儲存起來,接下來我們就可以按照題目要求,移動此人前面或者後面的人了,然後將此人插入到對應位置。我這裡多加了一個功能,如果移動步數大於此人身後的位置數量,則將此人移到隊尾,同理前移也是。

import java.util.Scanner;

public class 學生排隊 {
    public static void main(String[] args) {
        Scanner sc = new
Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int[] stu = new int[n]; for (int i = 0; i < n; i++) { // 初始化學生序列 stu[i] = i + 1; } for (int i = 0; i < m; i++) { int p = sc.nextInt(); int q = sc.nextInt(); // 找到對應學生 for (int j = 0; j < n; j++) { if (stu[j] == p) { // 判斷是向前移動還是向後移動 int temp = stu[j]; // 儲存要移動的學生的學號 int pos = j; int x = 0; if (q > 0) { //後移 if (q > n - pos - 1) { q = n - pos - 1; } while (x < q) { //我這裡是多加的功能,如果移動步數大於此人身後的位置數量,則移到隊尾,同理前移也是 stu[pos] = stu[pos + 1]; x++; pos++; } } else if (q < 0) { //前移 if (q < -pos) { q = -pos; } while (x > q) { stu[pos] = stu[pos - 1]; x--; pos--; } } stu[pos] = temp; break; } } } // 移動完成後,輸出最終序列 for (int y = 0; y < n; y++) { // 初始化學生序列 System.out.print(stu[y] + " "); } sc.close(); } }