全部评论 2

  • #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 50000+10
    int a[MAXN],b[MAXN],circle[MAXN],spin[MAXN];

    inline int read()//读入优化 不用写
    {
    char ch='';
    while(!isdigit(ch=getchar()));
    int num=ch-'0';
    while(isdigit(ch=getchar()))num=num
    10+ch-'0';
    return num;
    }
    int main()
    {
    int n;
    n=read();
    for(int i=1;i<=n;i++)
    {
    a[i]=read();b[i]=read();
    }
    circle[1]=1;
    circle[2]=a[1];//第一个点默认切环点
    for(int i=1;i<=n;i++)
    {
    if(b[a[i]]!=i&&a[a[i]]!=i||a[b[i]]!=i&&b[b[i]]!=i)//判断是否可行,由于是个圈,可逆,所以两次判定
    {
    printf("-1");
    return 0;
    }
    //if(i>1)
    if(a[circle[i]]==circle[i-1])circle[i+1]=b[circle[i]]; //由于你并不知道这两个同学的左右,所以判断一下,免得建环重复一个点
    else circle[i+1]=a[circle[i]];
    }
    int ans=n+10;//最多n-1,n+10没问题了
    for(int i=1;i<=n;i++)//这里开始是重点,就是找旋转次数,本蒟蒻一开始一直没理解,找大佬讲了好久才懂,如果旋转次相同,就可以看作与序列匹配,即为不用换位置的个数
    {
    spin[((i-circle[i]+n))%n];//直接膜就可以,+n把负数改过来,最后移动步数为0~n-1;
    ans=min(ans,n-spin[((i-circle[i]+n))%n]);//答案是否需要更新
    }
    memset(spin,0,sizeof(spin));//重新初始化,准备反跑
    memset(circle,0,sizeof(circle));
    circle[0]=1;
    circle[1]=b[1];
    for(int i=1;i<=n;i
    )
    {
    if(b[circle[i]]==circle[i-1])circle[i+1]=a[circle[i]];
    else circle[i+1]=b[circle[i]];//反跑直接反过来,ctrl+c&&ctrl+v
    }
    for(int i=1;i<=n;i++)
    {
    spin[((i-circle[i]+n))%n]++;
    ans=min(ans,n-spin[((i-circle[i]+n))%n]);//反跑反正数组不会变,一样的ctrl+c&&ctrl+v
    }
    printf("%d",ans);
    }

    有帮助,赞一个

    userId_undefined
    去预览
    此处输入正文,2千字以内,可点击右上角【去预览】按钮查看markdown展示效果
    0/2000发布
    全部评论 1
    userId_undefined
    🥥

    倔强青铜模拟·模拟练习生出道萌新
    运行超时,您的程序未能在规定时间内运行结束,请检查是否循环有误或算法复杂度过大

    2025-03-01 来自 甘肃

    0
    userId_undefined
    射手骑着龙——互

    回复
    🥥
    啊,ac,哪里运行错误?

    2025-04-14 来自 广东

    15小时前 来自 浙江

    0
  • 运行超时,您的程序未能在规定时间内运行结束,请检查是否循环有误或算法复杂度过大

    2025-03-01 来自 甘肃

    0
暂无数据

提交答案之后,这里将显示提交结果~

首页