1. 程式人生 > >ccf-csp201303-2 學生排隊

ccf-csp201303-2 學生排隊

問題描述

體育老師小明要將自己班上的學生按順序排隊。他首先讓學生按學號從小到大的順序排成一排,學號小的排在前面,然後進行多次調整。一次調整小明可能讓一位同學出隊,向前或者向後移動一段距離後再插入佇列。   例如,下面給出了一組移動的例子,例子中學生的人數為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,所有移動均合法。

思路:

Student類中id存學號,position存位置,vector模擬學生佇列。初始學號與位置相同。 1.對於每條命令找到對應id的student物件,修改position; 2.中間變數beforepo為移動前的位置,afterpo為移動之後所在的位置; 3.將對應student.position改為afterpo; 4.若為向後移動,將beforepo和afterpo之間的所有人的position減一(除移動的人自己之外); 5.若為向前移動,將beforepo和afterpo之間的所有人的position加一(除移動的人自己之外); 6.按照position的順序對vector排序,然後順序輸出id即可。

剛開始位置變更模擬沒有考慮到向前和向後移動的區別,浪費了挺多時間。另外不用陣列模擬的話這道題還可以用連結串列做。

100分程式碼:

#include<iostream>
# include<string>
# include<algorithm>
# include<vector>

using namespace std;

class Student   //Student類
	{
	public:
		int id;
		int position;
		public:
			void set_id(int a) { id = a; }
			void
set_position(int a) { position = a; } }; bool com(Student first, Student second)//最後按照position排序時的比較函式 { return first.position < second.position; } int main() { int n, num_order; cin >> n >> num_order; vector<Student> student; student.resize(n+1); for (int i = 0; i < n+1; i++) //初始佇列 { student[i].set_id(i); student[i].set_position(i); } vector<int> p; vector<int> q; p.resize(num_order+1); q.resize(num_order+1); p[0] = 0; q[0] = 0; for (int i = 1; i < num_order+1;i++) //輸入命令 { int temp1,temp2; cin >> temp1>>temp2; p[i]=temp1; q[i]=temp2; } for (int i = 1; i < num_order+1; i++) { int beforepo, afterpo,k; for (k = 0; k < n + 1; k++) //找到對應學號的學生 { if (student[k].id == p[i]) { beforepo = student[k].position; afterpo = student[k].position + q[i]; break; } } if (q[i] >= 0) //向後移動 { student[k].set_position(afterpo); for (int j = 1; j < n + 1; j++) if ((student[j].position > beforepo) && (student[j].position <= afterpo) && (student[j].id != p[i])) student[j].set_position(student[j].position - 1); } else //向前移動 { student[k].set_position(afterpo); for (int j = 1; j < n + 1; j++) if ((student[j].position >=afterpo) && (student[j].position <beforepo) && (student[j].id != p[i])) student[j].set_position(student[j].position + 1); } } sort(student.begin(), student.end(),com); //按照position排序 for (int i = 1; i < n + 1; i++) cout << student[i].id<<" "; }