日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 1248E Queue in the Train(大模拟)

發布時間:2024/4/11 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1248E Queue in the Train(大模拟) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:火車上有n個乘客,編號分別為1~n,編號為i的人會在第ti分鐘去打水,水箱每次只能給一個乘客使用,每位乘客都會使用水箱p分鐘,當一位乘客想要去打水時,他會先看編號在他前面的乘客是否都在座位上,如果有人沒在座位上,那么他會坐下來繼續等待,否則就會去水箱處排隊打水,當某一時刻有幾位乘客想同時打水時,編號小的乘客會優先打水,其他人會在水箱前面繼續等待,計算每個乘客打完水的時間

題目分析:面向題解編程。。。

因為題目好幾處涉及到了最值,比如最小編號,最小時間,所以我們需要選擇合適的容器進行處理,以達到減小時間復雜度并方便操作的目的

這里我們選擇的容器有:優先隊列、隊列、集合

首先建立兩個優先隊列,sitting與waiting,分別儲存“坐在座位上且時間沒到的人”與“坐在座位上且時間早就到達的人”

再建立一個隊列,queuing,儲存“在水箱前面排隊的人”

最后建立一個集合,empty_seat,儲存空的位置,我們可以很方便的用*empty_seat.begin()獲取編號最小的空位置

這樣一來按照題目直接模擬就好了,需要注意的細節如下:

  • 因為整個操作是對于當前時間而言的,所以每次只要時間更新,sitting與waiting都要實時更新
  • 操作優先級:queuing > waiting > sitting
  • 對于每次sitting與waiting的更新,我們分成兩個部分:
  • 若此時的時間now之前有人在水箱前面打水
  • sitting直接加入到水箱后排隊
  • waiting里的人繼續等待(因為waiting里的人早就滿足時間條件了,不滿足的是編號條件,這里一定需要想清楚再寫)
  • 若此時的時間now之前沒有人在水箱前面打水
  • sitting先加入到waiting中(滿足條件者)
  • waiting再加入到queuing中(滿足條件者)
  • 然后就是實現了,剩下的看注釋吧

    代碼:

    #include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;struct Node {int pos,start_time; };struct cmp_waiting {bool operator()(const Node& a,const Node& b){return a.pos>b.pos;} };struct cmp_sitting {bool operator()(const Node& a,const Node& b){if(a.start_time!=b.start_time)return a.start_time>b.start_time;return a.pos>b.pos;} }; //優先級:queuing > waiting > sitting priority_queue<Node,vector<Node>,cmp_waiting>waiting; priority_queue<Node,vector<Node>,cmp_sitting>sitting; queue<Node>queuing; set<int>empry_seat;LL ans[N];int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n;LL p,now;scanf("%d%lld",&n,&p);for(int i=1;i<=n;i++){Node temp;scanf("%d",&temp.start_time);temp.pos=i;sitting.push(temp);}now=sitting.top().start_time;empry_seat.insert(n+1);//將n+1置空,方便操作 while(sitting.size()||queuing.size()||waiting.size()){ while(queuing.size()&&queuing.front().start_time<=now)//如果有人在排隊,則優先處理排隊的人 {now+=p;//當前時間更新后,記得實時更新sitting和waiting ans[queuing.front().pos]=now;while(sitting.size()&&sitting.top().start_time<=now)//如果有新的人滿足時間條件了 //注意這里為什么值從sitting里拿而不在waiting里拿,是因為waiting里的人早就滿足時間約束了,只是不滿足編號約束,所以在這里肯定仍然不滿足編號約束{if(sitting.top().pos<*empry_seat.begin())//前面沒人在接水,直接去排隊 {queuing.push(sitting.top());empry_seat.insert(sitting.top().pos);//當前位置空了 sitting.pop();}else//否則加入到waiting里去等{waiting.push(sitting.top());sitting.pop();}}empry_seat.erase(queuing.front().pos);//接完水就回到座位上了 queuing.pop();}if(queuing.empty()&&waiting.empty())//如果排隊的人和等待的人都為空,說明時間太早了,直接快進 now=max(now,(LL)sitting.top().start_time);while(sitting.size()&&now>=sitting.top().start_time)//對滿足時間要求的人操作 {waiting.push(sitting.top());sitting.pop();}while(waiting.size()&&waiting.top().pos<*empry_seat.begin()){queuing.push(waiting.top());empry_seat.insert(waiting.top().pos);//只要離開座位就要加入這里 waiting.pop();}}for(int i=1;i<=n;i++)printf("%lld ",ans[i]);return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的CodeForces - 1248E Queue in the Train(大模拟)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。