hiho一下第167周数组重排

来源:互联网 发布:航天信息a6软件 编辑:程序博客网 时间:2024/05/24 05:13

题目摘要

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi想知道,如果他每次都按照一种固定的顺序重排数组,那么最少经过几次重排之后数组会恢复初始的顺序?

具体来讲,给定一个1 - N 的排列 P,小Hi每次重排都是把第 i 个元素放到第 Pi个位置上。例如对于 P = (2, 3, 1),假设初始数组是(1, 2, 3),重排一次之后变为(3, 1, 2),重排两次之后变为(2, 3, 1),重排三次之后变回(1, 2, 3)。

被排数组中的元素可以认为是两两不同的。

输入
第一行一个整数 N ,代表数组的长度。 (1 ≤ N ≤ 100)

第二行N个整数,代表1 - N 的一个排列 P 。

输出
输出最少重排的次数。

样例输入
3
2 3 1
样例输出
3

题目分析

拿到这道题一开始想到的就是初始化一个[1,n]的int型数组a[n],和一个长度为n的排列数组P,然后再申请一个和a[n]长度相同的int型数组b[n],将a[n]中第i个位置上的数放到b[p[i]]上,最后判断b[n]数组是不是[1,n]升序即可。

#include"stdio.h"#include"stdlib.h"#define M 100int main(){    int n, i, flag = 1, count = 0, p[M], a[M], b[M];    scanf_s("%d", &n);    //初始数组    for (i = 0; i < n; i++)    {        a[i] = i + 1;    }    //排列P    for (i = 0; i < n; i++)    {        scanf_s("%d", &p[i]);    }    while (flag==0 || count ==0)    {        //将第i个数放在Pi的位置上        for (i = 0; i < n; i++)        {            b[p[i]-1]=a[i];        }        //更新数组a        for (i = 0; i < n; i++)        {            a[i] = b[i];        }        count++;        for (i = 0; i < n - 1; i++)        {            if (b[i + 1] - b[i] != 1)            {                flag = 0;                break;            }            flag=1;        }    }    printf("%d\n", count);    system("pause");    return 0;}

但是测试只有90%AC,TIME LIMITED ERROR,于是又开始考虑另一种解法。
其实,每个位置都有对应的循环节,i位置上的数循环一定次数后一定会再次回到i,因此我们只要求出每个位置对应的循环节,再求出这些循环节的最小公倍数就是最后的解了。

#include"stdio.h"#include"stdlib.h"#define N 100int gcd(int x, int y){    return y ? gcd(y, x%y) : x;}int lcm(int x, int y){    return x*y / gcd(x, y);}int main(){    int a[N],n,i,p,count,lc=1;    scanf_s("%d", &n);    for (i = 1; i <= n; i++)    {        scanf_s("%d", &a[i]);    }    //考虑每个位置的循环节    for (i = 1; i <= n; i++)    {        if (i == a[i])continue;        else        {            p = a[i];            count = 1;            while (p != i)            {                p = a[p];                count++;            }            lc = lcm(lc, count);        }    }    printf("%d\n", lc);    system("pause");    return 0;}
原创粉丝点击