题解 P1053 【篝火晚会】
模拟
P1053
先解决
然后就是可行的情况,先把所期望的环的关系存储起来,用数组实现。当然期望环有两种情况,若视第一种情况为顺时针,那么第二种情况为逆时针:
输入: 第一种情况: 第二种情况:
4 1 1
3 4 4 3 3 4
4 3 2 2
1 2
1 2
设期望环中编号为
1 3
4 3 1 2
2 4
环一 环二
显然环一与环二是相同的。因此,我们可以将初始环(
初始环:
1
4 2
3
期望环第一种情况:经过3个单位长度
期望环第二种情况:经过1个单位长度
在同一种情况中经过相同单位长度的同学,我们可以把他们看做一个整体,这个整体是静止的(整体内部同学不会相对移动)。例如在第二种情况中可以把编号为
#include<bits/stdc++.h>
using namespace std;
const int N=1e4*5+5;
typedef int INT_N[N];
INT_N want_1,list_1,want_2,list_2,expect;
int n;
inline void read(int&number){
int un=1;
char letter=getchar();
number=0;
while(letter<'0'||'9'<letter){
un=letter^'-'?1:-1;
letter=getchar();
}
while('0'<=letter&&letter<='9'){
number=(number<<1)+(number<<3)+letter-'0';
letter=getchar();
}
number*=un;
}//快速读入
void init(){
read(n);
for(register int i=1;i<=n;i++)
read(want_1[i]),read(want_2[i]);
for(register int i=1;i<=n;i++)
if(want_1[want_1[i]]^i&&want_2[want_1[i]]^i||want_1[want_2[i]]^i&&want_2[want_2[i]]^i){
printf("-1\n");
exit(0);
}//当前同学希望的两个同学中如果有不希望当前同学的,不满足双向希望性,即不能满足每个同学的希望
expect[2]=want_1[expect[1]=1],expect[n]=want_2[1];//初始化期望环
for(register int i=2;i<n-1;i++)
expect[i+1]=want_1[expect[i]]^expect[i-1]?want_1[expect[i]]:want_2[expect[i]];//构造期望环
}
void work(){
int Max=0;
for(register int i=1;i<=n;i++)
list_1[(i+n-expect[i])%n]++,list_2[((n<<1)-i+2-expect[i])%n]++;//(i+n-expect[i])%n表示第一种情况,期望环中编号为i的同学经过的单位长度,((n-i+2)+n-expect[i])%n表示第二种情况,期望环中编号为n-i+2的同学经过的单位长度
for(register int i=0;i<n;i++)
Max=max(Max,max(list_1[i],list_2[i]));//表示更新经过单位长度为i的同学数(两种情况)
printf("%d\n",n-Max);
}
int main(){
init();
work();
return 0;
}