洛谷 P5462 X龍珠

2021-09-27 02:34:11 字數 1753 閱讀 3092

鏈結「x龍珠」是一款益智小遊戲。遊戲中有 n(2|n)n(2∣n) 個編號互不相同龍珠按照給定的順序排成乙個佇列,每個龍珠上面都有乙個編號。每次操作時,選擇並取出龍珠佇列中相鄰的兩個龍珠,放到目標佇列的末尾(目標佇列最開始是空的,且這兩個龍珠的前後順序不變),然後去除原龍珠佇列的空隙。反覆多次,直到原龍珠隊列為空。可見,因為決策不一樣導致目標佇列順序不一樣。現在請求出所有方案中、目標佇列字典序最大的方案。只需要給出目標佇列即可。

例如,當原龍珠佇列是 [1,3,2,4] 時,可以先取出 3 和 2,此時目標佇列是 [3,2],原龍珠佇列是 [1,4];再將剩下兩個龍珠放入目標佇列,得到目標佇列是 [3,2,1,4]

第一行,乙個整數 n。

接下來一行,每行 n 個整數,表示原龍珠佇列的編號。

一行,n 個整數。

輸入3 1 4 2

輸出4 2 3 1

輸入6 5 4 1 3 2

輸出6 5 4 1 3 2

說明/提示

對於 20% 的資料,n≤10。

對於 60% 的資料,n≤10^3。

對於 100% 的資料,n≤10^5,龍珠編號不超過 n。

用pre陣列和next陣列分別維護當前位置前乙個數的位置和後乙個數的位置,

pre[1]=-1,next[n]=-1;

用set維護遞增的序列,用pos陣列維護某個值的位置。

首先從set中取乙個最大值,判斷最大值後面是不是還有數字,如果沒有,那麼取乙個次大的。

我們知道要取的第乙個數之後,根據pos陣列得到這個數的下標記為index,然後利用next陣列得到下乙個數字的下標記為nindex.

用vis標記當前這個數有沒有被拿走,如果是0那麼沒被拿掉,否則被拿掉了.

標記這兩個數被拿走了,將這兩個數放入佇列中,從set中刪除掉這兩個數字。接下來更新pre陣列和next陣列。

next要更新的位置應該是pre[index],pre陣列要更新的位置是next[nindex]。

#includeusing namespace std;

const int n=1e5+10;

int pre[n],next[n],arr[n],pos[n],vis[n],n;

sets;

set::iterator it;

queueq;

void getnext(int index)

if(x==-1) next[index]=-1;

else next[index]=next[x];

}void getpre(int index)

if(x==-1) pre[index]=-1;

else pre[index]=pre[x];

}int main()

for(int i=1;i<=n/2;i++)

// printf("%d %d\n",arr[index],arr[nindex]);

s.erase(arr[index]),s.erase(arr[nindex]);

q.push(arr[index]),q.push(arr[nindex]);

vis[index]=vis[nindex]=1;//標記為已經消失

if(pre[index]!=-1) getnext(pre[index]);

if(next[nindex]!=-1) getpre(next[nindex]);

}while(!q.empty())

return 0;

}

題解 P5462 X龍珠

賽題 b p5462x龍珠 滿分 100分 發乙個set做法 維護兩個set,乙個按照順序排序,乙個按照值排序。每次從大往小取,問題就變成了判斷這個最大值後面是否有數,直接檢視一下按照順序排序的該數是否有後繼。編譯記得用c 11,請安心食用。為了方便理解,按照順序排序的set寫得不夠優美 winle...

Luogu P5462 X龍珠 貪心

題目鏈結 首先題目要求字典序最大,則顯然我們應該將大的數安排在前端。那麼現在來處理取相鄰數的問題,我們可以使用並查集維護 每個位置往後最近的未被取走的數的位置,下文用 fa i 表示。當乙個數 假定位置為 i 被取走時,將 fa i fa 查詢時直接取出即可。另外,當要取的數是最後乙個時,後面沒數,...

洛谷P5049 洛谷P5022 題解 旅行

原題 資料加強版 加強版 參考你谷題解 終於調過了 又是一如既往的申必錯誤 noi plus石錘了 原題的資料允許我們 o n 2 暴力斷邊,但是加強版的資料達到了 n log n 級別,我們必須在斷邊這一環節尋求更好的解法。考慮我們進入環後在何處回溯 根據繼續走環走到的點分類 設當前已經從 b 走...