CCF 201703-2 學生排隊 C語言程式碼(100分)
阿新 • • 發佈:2021-01-31
CCF 201703-2 學生排隊 C語言程式碼(100分)
問題描述
試題編號: 201703-2
試題名稱: 學生排隊
時間限制: 1.0s
記憶體限制: 256.0MB
問題描述:
問題描述
體育老師小明要將自己班上的學生按順序排隊。他首先讓學生按學號從小到大的順序排成一排,學號小的排在前面,然後進行多次調整。一次調整小明可能讓一位同學出隊,向前或者向後移動一段距離後再插入佇列。
例如,下面給出了一組移動的例子,例子中學生的人數為8人。
0)初始佇列中學生的學號依次為1, 2, 3, 4, 5, 6, 7, 8;
1)第一次調整,命令為“3號同學向後移動2”,表示3號同學出隊,向後移動2名同學的距離,再插入到佇列中,新佇列中學生的學號依次為1, 2, 4, 5, 3, 6, 7, 8;
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,所有移動均合法。
解題思路
本題是經典的雙重for迴圈的題型。用兩個for迴圈實現排隊功能。
詳細程式碼
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct{
int number;
int length;
}Move;
int main(int argc, char *argv[]) {
int n,m,i,j;
scanf("%d",&n);
scanf("%d",&m);
Move move[m];
for(i=0;i<m;i++){
scanf("%d %d",&move[i].number,&move[i].length);
}
int a[n+2],temp=0,tmp=0,flag=0;
for(i=1;i<n+1;i++){
a[i]=i;
}
a[0]=0;
a[n+1]=0;
for(i=0;i<m;i++){
if(move[i].length>0){
for(j=1;j<=n;j++){
if(a[j]==move[i].number){
flag=j;
}
}
temp=a[flag];
for(j=1;j<=move[i].length;j++){
a[flag+j-1]=a[flag+j];
}
a[flag+move[i].length]=temp;
}else{
for(j=1;j<=n;j++){
if(a[j]==move[i].number){
flag=j;
}
}
temp=a[flag];
tmp=abs(move[i].length);
for(j=1;j<=tmp;j++){
a[flag-j+1]=a[flag-j];
}
a[flag-tmp]=temp;
}
}
for(i=1;i<n+1;i++){
printf("%d ",a[i]);
}
return 0;
}