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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Train Wreck 模拟-建树-优先队列

發(fā)布時(shí)間:2025/3/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Train Wreck 模拟-建树-优先队列 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意 :

  • 類似于堆棧的火車站。給出長(zhǎng)為2n2n2n的括號(hào)序列,()分別代表放入火車站和推出火車站,又給了n輛火車的顏色。
  • 求構(gòu)造一個(gè)關(guān)于顏色的放入序列,滿足不存在同一放入火車的時(shí)刻在火車站內(nèi)顏色的序列相同。

思路 :

  • 將棧操作看作樹,要求轉(zhuǎn)化為給每一個(gè)節(jié)點(diǎn)染色,使得從根到每一個(gè)節(jié)點(diǎn)的鏈所構(gòu)成的顏色序列兩兩不同。注意到兩個(gè)都在第i層的節(jié)點(diǎn),如果它們父親不同,則從根到它們父親的鏈所構(gòu)成的顏色序列不同,這使得根到它們所構(gòu)成的顏色序列也一定不同。
  • 因此,問題轉(zhuǎn)化為,每個(gè)點(diǎn)的k個(gè)兒子顏色互不相同,對(duì)于一個(gè)節(jié)點(diǎn),假設(shè)有k個(gè)兒子,我們選取剩余火車數(shù)最多的k個(gè)顏色對(duì)應(yīng)上去即可(使用優(yōu)先隊(duì)列實(shí)現(xiàn))。

如下圖,

會(huì)發(fā)現(xiàn)在第一行和第二行的條件(顏色不同)滿足后,第三行的條件(大于一個(gè)數(shù)的顏色不同)自然會(huì)滿足,因此想到樹的性質(zhì),即讓父節(jié)點(diǎn)的每個(gè)兒子顏色互不相同。

#include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <vector> #include <unordered_map> #include <unordered_set> #include <set> #include <map> #include <stack> #include <queue> #include <deque> #define endl '\n' #define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define lowbit(x) (x&-x) using namespace std; const double pi = acos(-1); typedef long long ll; typedef pair<int, int> PII; typedef pair<long, long> PLL;const int N = 1e6 + 10;vector<int> G[N]; int pa[N], tot = 0; int a[N]; // 顏色i的數(shù)量 int ans[N]; // 火車序列為i的火車顏色int main() {IOS;int n;string s;cin >> n >> s;// 建樹int p = 0;for (auto ch : s)if (ch == '('){G[p].push_back( ++ tot);pa[tot] = p;p = tot;}elsep = pa[p];for (int i = 1; i <= n; i ++ ){int x;cin >> x;a[x] ++ ;}// 默認(rèn)是大頂堆priority_queue<PII> pq; // 對(duì)應(yīng)顏色的個(gè)數(shù),每種顏色for (int i = 1; i <= n; i ++ )pq.push({a[i], i});// 枚舉每個(gè)點(diǎn)for (int i = 0; i <= tot; i ++ ){vector<PII> ve; // 備份// 節(jié)點(diǎn)i的每個(gè)兒子for (int j = 0; j < G[i].size(); j ++ ){auto p = pq.top(); pq.pop();if (p.first == 0){cout << "NO" << endl;return 0;}ans[G[i][j]] = p.second;p.first -- ;ve.push_back(p);}for (auto p : ve)pq.push(p);}cout << "YES" << endl;for (int i = 1; i <= n; i ++ ) cout << ans[i] << " ";cout << endl;return 0; }

總結(jié)

以上是生活随笔為你收集整理的Train Wreck 模拟-建树-优先队列的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。