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

2022-06-08 21:51:17 字數 1669 閱讀 3714

你有一行盒子,從左到右依次編號為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。

例如當n=6時在初始狀態盒子序列為為:1 2 3 4 5 6; 

執行1 1 4後,盒子序列為:2 3 1 4 5 6; 

接下來執行2 3 5,盒子序列變為:2 1 4 5 3 6; 

再執行3 1 6,盒子序列變為:2 6 4 5 3 1; 

最終執行4,盒子序列變為:1 3 5 4 6 2。

【輸入格式】 

輸入包含不超過10組資料,每組資料第一行為盒子數n和指令m,以下m行每行包含一條指令。 

【輸出格式】 

每組資料輸出一行,即所有奇數字置的盒子編號之和。位置從左到右編號為1~n。 

整個題的題意非常簡明扼要,就是乙個順序鍊錶,要求在一定模擬操作後,求奇數字置的情況,但是如果繼續使用單向鍊錶來解決我們很難改變xy和位置,因為單向鍊錶中,我們無法表示這個鏈的順序,所以我們採用雙向鍊錶的方式解決問題

也就是對每個位置設定right和left兩個值,表示該位置的左右分別是什麼

使用link函式表示a和b接起來

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

處理完細節後,我們只需按要求隊程式進行順序模擬,用link函式按順序進行操作就可以模擬出操作後的鍊錶

需要注意的是,如果表的個數是偶數並且表處於反裝狀態,在最後求解時需要用所有位置的和減去奇數的和,才能得到真正的奇數字置的和。

1 #include2

using

namespace

std;

3int right1[100005],left1[100005];4

void link(int x,inty)5

9int

main()

10 19 right1[0]=1;left1[0]=n;

20for(int i=1;i<=m;i++)

2129

if(a==1&&left1[c]==b)continue;30

if(a==2&&right1[c]==b)continue;31

int lx=left1[b],ly=left1[c],rx=right1[b],ry=right1[c];

32if(a==1)33

38else

if(a==2)39

44else

if(a==3)45

51}52}

53int q=0,ans=0;54

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

5559

if(inv&&n%2==0)ans=(long

long)n*(n+1)/2-ans;

60 cout<

case

"<

61}

62return

0;

63 }

view code

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 表示反轉整條鏈。從操作1,2來看,需要有乙...

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...