計蒜客題目 法師康的工人
阿新 • • 發佈:2019-02-13
三個法師康的工人每天早上6點到工廠開始到三條產品生產線上組裝桔子手機。第一個工人在200時刻開始(從6點開始計時,以秒作為單位)在生產線上開始生產,一直到1000時刻。第二個工人,在700時刻開始,在1100時刻結束。第三個工人從1500時刻工作到2100時刻。期間最長至少有一個工人在生產線上工作的連續時間為900秒(從200時刻到1100時刻),而最長的無人生產的連續時間(從生產開始到生產結束)為400時刻(1100時刻到1500時刻)。
你的任務是用一個程式衡量N個工人在N條產品線上的工作時間列表(1≤N≤5000,以秒為單位)。
·最長的至少有一個工人在工作的時間段
·最長的無人工作的時間段(從有人工作開始計)
輸入第1行為一個整數N,第2-N+1行每行包括兩個均小於1000000的非負整數資料,表示其中一個工人的生產開始時間與結束時間。輸出為一行,用空格分隔開兩個我們所求的數。
樣例輸入
3 200 1000 700 1100 1500 2100
樣例輸出
900 400
#include<stdio.h> #include<algorithm> using namespace std; struct worker{ int stime; int etime; bool operator < (const worker &x) const{//過載運算子,使排序時,stime小的靠前,stime相同時etime小的靠前 if(stime!=x.stime) return stime<x.stime; else return etime<x.etime; } }buf[5000]; int main() { int n; scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d%d",&buf[i].stime,&buf[i].etime); if(n==1){//對於只有1個人的特殊處理 printf("%d 0",buf[0].etime-buf[0].stime); return 0; } sort(buf,buf+n); worker pre=buf[0], p=buf[1]; int wtime=buf[0].etime-buf[0].stime, ntime=0, end=buf[0].etime; int flag=0; for(int i=1;i<n;){ if(end>=p.stime){//若結束時間大於下一個的開始時間(無間斷) end=end>p.etime?end:p.etime; } else{//結束時間小於下一個的開始時間(有間斷) wtime=wtime>(end-pre.stime)?wtime:(end-pre.stime); ntime=ntime>(p.stime-end)?ntime:(p.stime-end); end=p.etime; pre=p; } i++; p=buf[i]; } printf("%d %d",wtime,ntime); return 0; }
思路:對工作時間進行排序,若工作時間之間沒有間斷,則不斷更新目前的結束時間end,若工作時間之間有間斷,則計算最大工作時間,最大空閒時間,並更新end。以此迴圈整個工作時間列表。在程式碼中,用pre和p代表前一個工作時間和當前的工作時間,用end記錄目前的結束時間。遍歷時判斷:end是否大於等於p的結束時間?若是,則更新end(取目前end與p結束時間之間的較大值),若不是,則計算工作時間wtime與ntime,同時更新end
總結:思考很重要,同時注意結束時間與開始時間相等時,也是可以無縫接上的。