UVA 12657 移動盒子 最詳細講解

2021-10-05 18:43:38 字數 2219 閱讀 3224

題目鏈結

有一行從左到右編號為 1,2 ,3,4……n 的盒子,定義以下四種指令:

① 1 x y :將編號為x 的盒子移動到 y 的左邊(若x已在 y 的左邊,則忽略此指令)

② 2 x y : 將編號為 x 的盒子移動到 y 的右邊 (若x 已在y的右邊,則忽略此指令)

③ 3 x y :交換 x 和 y 盒子的位置

④ 4 : 將所有的盒子逆序

輸入:輸入不超過10組資料,對於每組資料,第一行輸入兩個數字,分別為盒子的個數 n 以及 指令的數量 m,接下來的 m 行 給出 m 條指令。

輸出:完成指令後的在 奇數字置(從左往右)的盒子的編號和 。

直接模擬 指令操作即可,但是不能用陣列來儲存盒子,會超時。

盒子的移動 不僅涉及到給定的 x 和 y ,還有x 和 y 周圍的盒子,所以,應使用 雙向鍊錶 而不是 單向鍊錶 的形式來儲存盒子,雙向鍊錶可以使用雙指標實現,但是也可以採用兩個位置陣列 left 和 right 實現,並且後者效率更高,因為它可以像陣列一樣使用下標來直接定位。

void

link

(int l ,

int r )

對於第四個指令,即逆序操作,我們不需要真的將其逆序,我們只要設定乙個標記 flag ,flag 初始化為 0 ,表示並未執行過 逆序,而後每當執行一次 逆序指令,我們讓 flag = ! flag,最後,我們根據flag 的值,如果是 1 ,說明 最終是需要逆序的,如果flag 是 0,那麼說明沒有執行過 逆序指令或者 執行了偶數個逆序指令。

ps:如果採用標記符的方式來處理逆序指令,那麼執行其他的指令時,可能需要根據 flag 的狀態來進行一定的調整。

對於雙向鍊錶,我們可以將其頭尾相連,形成乙個環結構,從而可以保證後續操作的統一性,而不用去專門判斷是否為 頭節點 和 尾節點。

6 .對於 指令3 ,即交換指令,它不受flag 的影響,但是交換的過程卻和 x 與 y 的相對位置有關:

最終**如下:

#include

using

namespace std;

int n,m,kase;

const

int maxn =

100000+10

;int left[maxn]

,right[maxn]

;void

link

(int l,

int r)

intmain()

right[0]

=1, left[0]

= n;

int op, x, y;

bool flag =

false

;while

(m--

)scanf

("%d %d"

,&x,

&y);

if(op==

3&& right[y]

==x)

swap

(x,y);if

(op!=

3&& flag) op =

3- op;

// 逆序下,左移指令實際是右移,右移指令實際是左移指令。

if(op==

1&& x == left[y]

)continue;if

(op==

2&& x == right[y]

)continue

;int lx = left[x]

, ly = left[y]

, rx = right[x]

, ry = right[y];if

(op==1)

else

if(op==2)

else

else}}

long

long ans =0;

// int 可能會溢位

int s =0;

for(

int i =

1; i <= n;

++i)

// cout << ans << endl;

if(flag && n%2==

0) ans =

(long

long

)n*(n+1)

/2- ans;

// 逆序後的奇數是偶數,偶數是奇數

printf

("case %d: %lld\n"

,++kase,ans);}

}

uva12657 移動盒子

你有一行盒子,從左到右依次編號為1,2,3,n。可以執行以下4種指令 1 x y 表示把盒子x移動到盒子y的左邊 如果x已經在y的左邊則忽略此指令 2 x y 表示把盒子x移動到盒子y的右邊 如果x已經在y的右邊則忽略此指令 3 x y 表示交換盒子x和y的位置。4 表示反轉整條鏈。指令保證合法,即...

6 5 移動的盒子 uva12657

較為複雜的一題 有點類似6 1 但是分析完之後比6 1簡單 就是按照思路模擬就好!學會了雙向鍊錶 先初始化 link是關鍵 分析命令 可以大大簡化 反轉鍊錶不用反轉 改操作和輸出就行 includeusing namespace std void link int int int left1 100...

Uva 12657 移動盒子(雙向鍊錶)

你有一行盒子,從左到右依次編號為1,2,3,n。可以執行以下4種指令 1 x y表示把盒子x移動到盒子y左邊 如果x已經在y的左邊則忽略此指令 2 x y表示把盒子x移動到盒子y右邊 如果x已經在y的右邊則忽略此指令 3 x y表示交換盒子x和y的位置。4 表示反轉整條鏈。指令保證合法,即x不等於y...