(本人本題完成於2016-7-20)
題目大意:有一些點以1,2,3,...,n(3≤n≤50000)的順序排成乙個環,要求將其中一些點進行置換,使得置換後排成的環滿足給定的條件:第1個點與第a1,b1個點相鄰,第2個點與第a2,b2個點相鄰,...,第n個點與第an,bn個點相鄰。如果可以滿足條件,求出至少要置換多少個點,否則輸出-1。
做法:我們可以轉換一下思路,要求至少要置換多少個點,可以先求至多可以不置換多少個點。首先按照給定的條件構成乙個環,並對每個點的度數進行累加。我們知道,乙個環內的節點度數都是2,在累加中,如果發現乙個點的度數超過2,則一定無法滿足條件。但這裡還有乙個情況,倘若按照給定條件形成了多個環,依照題目定義也是無法滿足條件的,因此要進行特殊判斷。構成環後,以標號為1的點為起始點遍歷環,可以得到正反兩個序列,可以發現這兩個序列在經過一定的旋轉操作後(別忘了這是乙個環)是正好相反的。將這兩個序列分別與1,2,3,...,n這個序列做差,如果結果小於0就加上n,就可以得到乙個數列r。容易想到,如果r[i]=r[j],就表示經過一定的旋轉操作後i和j可以同時落在自己的位置上,於是,我們只要求出最多有多少個r[i]相同,就是至多可以不置換的點數。
以下是本人**:
#include
#include
#include
#include
#include
using
namespace
std;
intn,con[
50010][2
]=,deg[
50010
]=,q[
50010
]=,v[
50010
]=;int
ans=
99999999
;void
work()
if(n-mvoid
reverse()
}int
main()
} for(
inti=
0,j=
1;;)
//求出其中乙個序列
//如果序列內的點數還沒達到n,而已經無法再擴充套件,則判斷為有多個環,無解
else
break
; }
work();
//做差
reverse();
//反轉序列
work();
//再一次做差
printf
("%d"
,ans);
return0;
}
篝火晚會(NOIP 2005 提高組 第三題)
篝火晚會 noip 2005 提高組 第三題 題目概述 一共有n個同學,編號從1到n。一開始,同學們按照1,2,n的順序坐成一圈,實際上每個人都有兩個最希望相鄰的同學。每乙個命令的形式如下 這裡m的值是由佳佳決定的,每次命令m的值都可以不同。這個命令的作用是移動編號是b1,b2,bm的這m個同學的位...
NOIP2005 篝火晚會
題目 分析 置換群.首先理解題意 b1,b2,bn是無限制的,並非連續,並非遞增,隨便選。於是可以形成若干個環,乙個環的花費是這個環包含的元素個數。所以,最小花費就是多少個人不在應在的位置上。再,多少個人不在應在的位置上 n 最多多少人在應在的位置上。然後,這個可以用偏移量求,求偏移量中包含元素最多...
Noip2005 篝火晚會
佳佳剛進高中,在軍訓的時候,由於佳佳吃苦耐勞,很快得到了教官的賞識,成為了 小教官 在軍訓結束的那天晚上,佳佳被命令組織同學們進行篝火晚會。一共有nnn個同學,編號從111到nnn。一開始,同學們按照1,2,n1,2,n1,2,n的順序坐成一圈,而實際上每個人都有兩個最希望相鄰的同學。如何下命令調整...