P1053 篝火晚会

题目来源:https://www.luogu.org/problemnew/show/P1053(题目太长。。。。)

求出期望环与实际环的差,

ans=总人数-不同的人数

期望环的构建 将h[1]=1.h[2]=b[1],h[n]=a[1] ,h[2]和h[n]交换是无所谓的

至于判断不同的人数 对于置换得到的数列,找每个数距离初始状态的长,统计相同长的个数即可。

不过一开始要特判下是否可以 如果a想要b在他附近,而b不想要a在他附近那么就不能的直接输出-1

这题本来不想发的,,然而。。。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<vector>
using namespace std;
#define int long long
#define olinr first
#define nmr second
#define love_nmr 0 
int n;
pair<int,int> like[50505];
int huan[50505];
int olinr_nmr[50505];
int nmr_olinr[50505];
inline int read()
{
    int x=0,f=1; 
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            f=-f;
        ch=getchar();
    } 
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
        put(x/10);
    putchar(x%10+'0');
}
signed main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        like[i].olinr=read();
        like[i].nmr=read();
    }
    for(int i=1;i<=n;i++)
        if((like[like[i].olinr].nmr!=i&&like[like[i].olinr].olinr!=i)||(like[like[i].nmr].nmr!=i&&like[like[i].nmr].olinr!=i))
        {
            put(-1);
            return 0;
        }
    huan[1]=1;
    huan[n]=like[1].olinr;
    huan[2]=like[1].nmr;
    for(int i=3;i<n;i++)
        if(like[huan[i-1]].olinr==huan[i-2])
            huan[i]=like[huan[i-1]].nmr;
        else
            huan[i]=like[huan[i-1]].olinr;
    for(int i=1;i<=n;i++)
    {
        nmr_olinr[(huan[i]+i-1)%n]++;
        olinr_nmr[(huan[i]-i+n)%n]++;
    }
    int love=0;
    for(int i=0;i<n;i++)
        love=max(love,max(nmr_olinr[i],olinr_nmr[i]));
    put(n-love);
    return love_nmr;
}

猜你喜欢

转载自www.cnblogs.com/olinr/p/9419303.html
今日推荐