CCF CSP 201709-2 公共鑰匙盒 思路分析和經驗總結

  • First and Foremost

    這個題做了挺長時間的,原因是我想不用STL和結構體來解這道題。畢竟這僅是第二道題。可是事實上我低估它了,或者說是因爲我的技術還不夠——我沒有把它figue out。最後我還是下定主意複習一下STL,然後參考了【meelo】大神的【文章】,重新做了這道題。

  • 問題描述

試題編號: 201709-2
試題名稱: 公共鑰匙盒
時間限制: 1.0s
內存限制: 256.0MB
問題描述:

問題描述

  有一個學校的老師共用N個教室,按照規定,所有的鑰匙都必須放在公共鑰匙盒裏,老師不能帶鑰匙回家。每次老師上課前,都從公共鑰匙盒裏找到自己上課的教室的鑰匙去開門,上完課後,再將鑰匙放回到鑰匙盒中。
  鑰匙盒一共有N個掛鉤,從左到右排成一排,用來掛N個教室的鑰匙。一串鑰匙沒有固定的懸掛位置,但鑰匙上有標識,所以老師們不會弄混鑰匙。
  每次取鑰匙的時候,老師們都會找到自己所需要的鑰匙將其取走,而不會移動其他鑰匙。每次還鑰匙的時候,還鑰匙的老師會找到最左邊的空的掛鉤,將鑰匙掛在這個掛鉤上。如果有多位老師還鑰匙,則他們按鑰匙編號從小到大的順序還。如果同一時刻既有老師還鑰匙又有老師取鑰匙,則老師們會先將鑰匙全還回去再取出。
  今天開始的時候鑰匙是按編號從小到大的順序放在鑰匙盒裏的。有K位老師要上課,給出每位老師所需要的鑰匙、開始上課的時間和上課的時長,假設下課時間就是還鑰匙時間,請問最終鑰匙盒裏面鑰匙的順序是怎樣的?

輸入格式

  輸入的第一行包含兩個整數NK
  接下來K行,每行三個整數wsc,分別表示一位老師要使用的鑰匙編號、開始上課的時間和上課的時長。可能有多位老師使用同一把鑰匙,但是老師使用鑰匙的時間不會重疊。
  保證輸入數據滿足輸入格式,你不用檢查數據合法性。

輸出格式

  輸出一行,包含N個整數,相鄰整數間用一個空格分隔,依次表示每個掛鉤上掛的鑰匙編號。

樣例輸入

5 2
4 3 3
2 2 7

樣例輸出

1 4 3 2 5

樣例說明

  第一位老師從時刻3開始使用4號教室的鑰匙,使用3單位時間,所以在時刻6還鑰匙。第二位老師從時刻2開始使用鑰匙,使用7單位時間,所以在時刻9還鑰匙。
  每個關鍵時刻後的鑰匙狀態如下(X表示空):
  時刻2後爲1X345;
  時刻3後爲1X3X5;
  時刻6後爲143X5;
  時刻9後爲14325。

樣例輸入

5 7
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9

樣例輸出

1 2 3 5 4

評測用例規模與約定

  對於30%的評測用例,1 ≤ NK ≤ 10, 1 ≤ w ≤ N, 1 ≤ sc ≤ 30;
  對於60%的評測用例,1 ≤ NK ≤ 50,1 ≤ w ≤ N,1 ≤ s ≤ 300,1 ≤ c ≤ 50;
  對於所有評測用例,1 ≤ NK ≤ 1000,1 ≤ w ≤ N,1 ≤ s ≤ 10000,1 ≤ c ≤ 100。

 

  • 解題代碼

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct teacher{
    int time;//取/還時間點。
    int fetchOrReturn;//1爲取;0爲還.
    int keyNum;//鑰匙編號。
    teacher(int t, bool f, int k):time(t), fetchOrReturn(f), keyNum(k){}//用參數列表的形式賦值。
    bool operator <(teacher tea){//重載"<"運算符。
        if(time < tea.time) return true;
        else if(time == tea.time && fetchOrReturn < tea.fetchOrReturn) return true;//先還後取。
        else if(time == tea.time && fetchOrReturn == tea.fetchOrReturn && keyNum < tea.keyNum)
            return true;//如果有多位老師還鑰匙,則他們按鑰匙編號從小到大的順序還。
        else return false;
    }
};
int main()
{
    int totalKeys, teacherNum;//鑰匙串數量,教師數量。
    cin>>totalKeys>>teacherNum;
    vector<teacher> teachVec;//使用vector記錄教師取/還鑰匙的信息。
    for(int i = 0; i < teacherNum; i++){
        int key, startTime, endTime;
        cin>>key>>startTime>>endTime;
        teachVec.push_back(teacher(startTime, 1, key));
        teachVec.push_back(teacher(startTime+endTime, 0, key));
    }
    sort(teachVec.begin(), teachVec.end());//快速排序。
    int keyArray[totalKeys + 1];//鑰匙串序列。
    for(int i = 1; i <= totalKeys; i++){
        keyArray[i] = i;//默認是升序排列。
    }
    for(int i = 0; i < teachVec.size(); i++){
        if(teachVec[i].fetchOrReturn == 1){//1爲取鑰匙串。
            for(int j = 1; j <= totalKeys; j++){
                if(teachVec[i].keyNum == keyArray[j]){
                    keyArray[j] = 0;//將鑰匙串取走。
                    break;
                }
            }
        }else{//還鑰匙串。
            for(int j = 1; j <= totalKeys; j++){
                if(keyArray[j] == 0){
                    keyArray[j] = teachVec[i].keyNum;
                    break;
                }
            }
        }
    }
    for(int i = 1; i <= totalKeys; i++){//打印輸出。
        cout<<keyArray[i]<<" ";
    }
}
  • 思路分析

    使用STL中的vector向量容器存放【取鑰匙串/放鑰匙串】的序列。將這一序列進行sort快速排序。根據排序後的結果對鑰匙串序列進行修改。

  • 經驗總結

    能使用STL的話,儘量用。在之前使用過Java中的容器,很好用。本來因爲c++中的容器參數太多,不好記,所以不想用。但是現在看來,想多了。STL真香。

    【引用羅茜大神的話】C++中的sort函數:其實有時候sort函數比qsort函數還要稍微快那麼一點,它使用的排序方法是類似於快排的方法,時間複雜度爲n*log2(n),並且用起來比較方便,有排序用sort函數,不能用創造機會也要用!
頭文件:#include<algothrim>
調用參數:sort(排序首地址,排序末地址,定義排序方式的函數名(可有可無)),如果沒有排序方式默認按照升序排列。
現在我們就解決一下如何按照降序方式排列。
  1,對int型數組a[n]降序排:

  bool cmp (int a, int b)
  {
    return a > b;
  }//降序

  2,對string型的數組a[n]排序:

  bool cmp (string a, string b)
  {
    return a > b;
  }//降序

  3,對結構體型的數組a[n]排序:

  bool cmp (node a, node b)
  {
    return a.x > b.x;
  }//降序
  ps:如果對結構體進行二級排序,只需在排序函數裏面加上if語句。
  以上所有的排序函數調用的時候都是用:sort(a, a+n, cmp);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章