CF-Codeforces Round #485 (Div. 2)-E-Petr and Permutations

ACM模版

描述

这里写图片描述

题解

初始给定一个 1n 1 ∼ n 的全排列,经过 3n 3 n 次随机交换或者 7n+1 7 n + 1 次随机交换,得到一个新的全排列,问这个全排列是通过 3n 3 n 次随机交换还是 7n+1 7 n + 1 次随机交换形成的?

这个题很简单,放在 E E 有些坑了……昨天晚上连题都没有来得及看。

首先,我们分析,两个数经过 2x+1 交换相当于经过 1 1 次交换,经过 2x 次交换,相当于没有交换,如果不止两个数来回交换,而是多个数之间来回交换,那么可以看成一个环,道理是一样的。所以不管是哪种交换,里面一定存在很多没有实际效果的交换,也就是 2x 2 x 次交换。

这里我们可以假设是通过 3n 3 n 次操作获得的全排列,那么 3n=2x+cnt 3 n = 2 x + c n t 2x 2 x 具体是多少我们无法直接求出来,因为它是无实际效果的,但是我们可以求出来 cnt c n t cnt c n t 表示有效的操作次数,经过有效的操作次数我们得到了这个全排列,那么我们同样可以通过 cnt c n t 次操作来恢复到初始化的 1n 1 ∼ n 有序的全排列,如此这般我们就可以求出 cnt c n t ,得到 y=3ncnt y = 3 n − c n t ,此时我们判断一下,如果 y=2x y = 2 x ,那么说明我们先前的假设是对的,反之说明这个全排列是经过 7n+1 7 n + 1 次操作获得的(代码 One)。

在查看别人的代码时,发现了一种很莫名其妙的解法(代码 Two),实在是参悟不透,也发一下,如果大佬们有何高见,请指点。

代码

One:

#include <cstdio>

const int MAXN = 1e6 + 10;

int n;
int a[MAXN], p[MAXN];

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", a + i);
        p[a[i]] = i;
    }

    int cnt = 0;
    for (int i = 1; i <= n; i++)
    {
        if (a[i] == i)
        {
            continue;
        }

        cnt++;
        a[p[i]] = a[i];
        p[a[i]] = p[i];
    }

    if ((3 * n - cnt) % 2 == 0)
    {
        printf("Petr");
    }
    else
    {
        printf("Um_nik");
    }

    return 0;
}

Two:

//  AC
//#include <iostream>
//#include <cstdio>
//
//using namespace std;
//
//int n;
//
//int main()
//{
//    scanf("%d", &n);
//
//    int cnt = 0, x;
//    for (int i = 1; i <= n; i++)
//    {
//        scanf("%d", &x);
//        cnt += (x == i);
//    }
//
//    if (cnt >= n / 1000)
//    {
//        puts("Petr");
//    }
//    else
//    {
//        puts("Um_nik");
//    }
//
//    return 0;
//}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值