1. 程式人生 > >CCF — 學生排隊(Python實現:100分)

CCF — 學生排隊(Python實現:100分)

2017.03.2 學生排隊

目錄

前言

前言

最近我在做CCF的題目,也打算把每道題的解題思路都寫到部落格上來,希望能幫助到也在做CCF題目的讀者們,希望你們通過本文能有所提示,幫助大家提升程式設計能力。另外有個很好的想法就是,建議讀者們可以先看一下問題分析的部分,然後自己再整理一下思路,重新做一遍,最後再參考程式碼,我想這樣會更有收穫。
 

一、問題描述

問題描述

體育老師小明要將自己班上的學生按順序排隊。他首先讓學生按學號從小到大的順序排成一排,學號小的排在前面,然後進行多次調整。一次調整小明可能讓一位同學出隊,向前或者向後移動一段距離後再插入佇列。

例如,下面給出了一組移動的例子,例子中學生的人數為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,所有移動均合法。

二、問題分析

這道題是關於列表元素調整順序的問題,主要的解題思路如下:

①先把輸入資料部分完成,把學生儲存在peo列表中,把m次調整方案儲存在adjust的m行2列的二維列表中

②遍歷m次,每次都依次取出調整的學生號調整值以及找出當前學生在列表中的下標,然後把該學生刪掉,同時在列表末尾新增一個0元素

③接著從後往前迴圈學生列表,到刪除學生的下標+1為止,依次互換列表中的值,直到0元素到達刪除的學生下標處;接著要做的就是把刪除的學生號重新賦值進去0的位置。

這樣,整道題就結束了。

三、程式說明

n:輸入n個學生

m:調整m次

peo:儲存學生的列表

adjust:調整的方案,一個m行2列的二維列表

python語言的程式如下(100分):

# 學生排隊

n = int(input())
m = int(input())
peo = [int(i) for i in range(1,n+1)]
adjust = [[0 for i in range(2)] for j in range(m)]
for i in range(m):
    adjust[i][:] = [int(x) for x in input().split()]

for i in range(m):
    p = adjust[i][0] # 調整的學生
    q = adjust[i][1] # 調整
    k = peo.index(p) # 學生下標
    k += q # 調整後的下標
    peo.remove(p)
    peo.append(0)
    for j in range(k+1,n)[::-1]:
        peo[j],peo[j-1] = peo[j-1],peo[j]
    peo[k] = p

for i in peo:
    print(i,end=' ')