洛谷P1053篝火晚會題解 zhengjun

2021-10-23 03:35:12 字數 3285 閱讀 4437

題目描述

佳佳剛進高中,在軍訓的時候,由於佳佳吃苦耐勞,很快得到了教官的賞識,成為了「小教官」。在軍訓結束的那天晚上,佳佳被命令組織同學們進行篝火晚會。一共有n

nn個同學,編號從1

11到n

nn。一開始,同學們按照1,2

,…,n

1,2,…,n

1,2,…,

n的順序坐成一圈,而實際上每個人都有兩個最希望相鄰的同學。如何下命令調整同學的次序,形成新的乙個圈,使之符合同學們的意願,成為擺在佳佳面前的一大難題。

佳佳可向同學們下達命令,每乙個命令的形式如下:

( b1

,b2,

...b

m−1,

bm

)(b_1, b_2,... b_, b_m)

(b1​,b

2​,.

..bm

−1​,

bm​)

這裡m

mm的值是由佳佳決定的,每次命令m

mm的值都可以不同。這個命令的作用是移動編號是b1,

b2,…

,b

mb_1,b_2,…, b_m

b1​,b2

​,…,

bm​的這m

mm個同學的位置。要求b

1b_1

b1​換到b

2b_2

b2​的位置上,b

2b_2

b2​換到b

3b_3

b3​的位置上,……,要求b

mb_m

bm​換到b

1b_1

b1​的位置上。執行每個命令都需要一些代價。我們假定如果乙個命令要移動m

mm個人的位置,那麼這個命令的代價就是m

mm。我們需要佳佳用最少的總代價實現同學們的意願,你能幫助佳佳嗎?

輸入格式

第一行是乙個整數n(3

≤n

≤50000

)n(3 \le n \le 50000)

n(3≤n≤

5000

0),表示一共有n

nn個同學。

其後n

nn行每行包括2

22個不同的正整數,以乙個空格隔開,分別表示編號是1

11的同學最希望相鄰的兩個同學的編號,編號是2

22的同學最希望相鄰的兩個同學的編號,……,編號是n

nn的同學最希望相鄰的兩個同學的編號。

輸出格式

乙個整數,為最小的總代價。如果無論怎麼調整都不能符合每個同學的願望,則輸出−1-1

−1。輸入輸出樣例

輸入 #1 複製

434

4312

12

輸出 #1 複製
2
說明/提示

對於30

%30\%

30%的資料,n

≤1000

n \le 1000

n≤1000

;對於全部的資料,n

≤50000

n \le 50000

n≤5000

0。2005

2005

2005

提高組第三題

首先,為了讓總代價最少,一定就要讓移動的人次最少,我們方法就是找到一組盡可能多的不用移動的,而剩下的一坨,有可能是一次換的,有可能是兩次……但是,無論是多少次,最少的代價一定就是總個數,因為每個人只需要換一次就可以到達他的位置,連成乙個環,如果還有其他的環,就再每人換一次,又成乙個環,知道換完位置。這樣每個人就只需要移動一次就夠了。

那麼,問題就轉換成了求最多可以有多少個人不用動。

所以,我就打了乙個模擬,直接從頭到尾看看有多少不用動,結果,聽取wawa

wa聲一片

額,我再乍一看,乙個是初始環,另乙個是目標環,要找到最多能有多少一樣的,應該要一次一次對過去,然後,有乙個方法,就是求出他要移動多少格才可以到達最後的目標點。

這樣,移動格數相同的就一定是同一組的,也就是同一次移動的,然後找到最多的一組就可以了。

結果**一交,又是wawa

wa

然後又細細一想,啊,目標環還有可能是另乙個方向擺的,就是比如說樣例,可能是1 3 2 4,也有可能是1 4 2 3,所以就要兩次。

結果交上去,終於acac

ac了(太不容易了)

#include

#define max(x,y) ((x)>(y)?(x):(y))

#define maxn 50001

using

namespace std;

int n;

int a[maxn]

,b[maxn]

;//每個點的兩邊的點

bool flag[maxn]

;//判斷是否已經用過了

int k[maxn]

,f[maxn]

;//目標序列,距離目標點有多少距離

int sum[maxn]

;//桶計數

intmain()

elseif(

!flag[b[now]])

else

}for

(int i=

1;i<=n;i++

)f[i]

=(i-k[i]

+n)%n;

//求距離

int maxx=0;

for(

int i=

1;i<=n;i++

)//重來一遍

memset

(sum,0,

sizeof

(sum));

//清空

memset

(flag,0,

sizeof

(flag));

//清空

now=1;

k[1]=

1;flag[now]=1

;for

(int i=

2;i<=n;i++

)elseif(

!flag[a[now]])

}for

(int i=

1;i<=n;i++

)f[i]

=(i-k[i]

+n)%n;

for(

int i=

1;i<=n;i++

)printf

("%d"

,n-maxx)

;//注意最後要用來減

return0;

}

洛谷P1053 篝火晚會

題目 模擬,構造出整個數列,要求的就是這個數列需要經過多少次操作得到 但是,這其實是乙個環,編號為1的可以放任意乙個位置,每一位都可以右移一位,最右邊的一位移到第一位 後文直接叫右移 而且,第乙個人可以選擇左邊a 1 右邊b 1 也可以左邊b 1 右邊a 1 所以環還可以倒過來。比如題中所給資料 4...

洛谷 P1053 篝火晚會

佳佳剛進高中,在軍訓的時候,由於佳佳吃苦耐勞,很快得到了教官的賞識,成為了 小教官 在軍訓結束的那天晚上,佳佳被命令組織同學們進行篝火晚會。一共有nn n個同學,編號從11 1到nn n。一開始,同學們按照1,2,n1,2,n1,2,n的順序坐成一圈,而實際上每個人都有兩個最希望相鄰的同學。如何下命...

P1053 篝火晚會

至於思路以及 解釋,個人覺得洛谷的題解已經很清楚了,故就不多解釋了 有一點不是很清楚,就是如果將c陣列的初始值定義為 正 c 0 1 c 1 l 1 反 c 0 1 c 1 r 1 時會wa乙個點,但在我看來好像並沒有什麼區別,如果有人知道,可以在下面告訴我,萬分感謝 include include...