zoukankan      html  css  js  c++  java
  • 【t013】无聊的军官

    Time Limit: 1 second
    Memory Limit: 32 MB

    【问题描述】

    每个学年的开始,高一新生们都要进行传统的军训。今年有一个军训教官十分奇怪,他为了测试学员们的反应能力,每次吹哨后学员们都会变换位置。每次左数第I位学员都会站到第ai个位置,经过若干次之后,队伍又会回到原来的样子。你的任务是计算n个人的队伍至少经过多少次之后,队伍恢复到原来样子。
    

    【输入格式】

    输入文件的第一位包含一个整数N(0<N10000),表示队伍的人数。
    接下来N行,每行一个正整数ai表示左起第i个人接下来出现在左起第ai个位置上。
    

    【输出格式】

    仅包括一行,一个正整数M,表示军官居最少的吹哨次数。
    

    【输入样例1】

    5
    2
    3
    4
    5
    1
    

    【输出样例1】

    5
    

    【数据规模】

    对于30%的数据,有N ≤100;
    对于100%的数据,有N ≤10000;
    对于全部数据,答案均在64位整数范围之内。
    

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t013

    【题意】

    中文题..

    【题解】

    那个变化位置的序列最后肯定能够形成若干个环的;
    每个环的大小就是每个人回到原来位置所需要的步骤数;
    那么求这几个环的大小的最小公倍数就好了;
    这里我先把环的大小这些数字质因数分解一下;
    然后按照每个因数出现次数最多的,作为这个因数的出现次数;
    然后每个因数^(因数的出现次数)全部乘起来就好;
    先求gcd再相乘除它也能求最小公倍数;
    但好像会超时.
    (没看到题目下面的数据范围,写了个高精度…)

    【完整代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int MAXN = 1e4+100;
    
    int a[MAXN],n;
    bool bo[MAXN];
    vector <int> v,what,zhi;
    int num[MAXN],ans[MAXN],al;
    
    bool is(int x)
    {
        double t = x;
        int len = int(sqrt(t));
        rep1(i,2,len)
            if (x%i==0)
                return false;
        return true;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(n);
        rep1(i,1,n)
            rei(a[i]);
        rep1(i,2,n)
            if (is(i))
                zhi.pb(i);
        rep1(i,1,n)
            if (!bo[i])
            {
                int j = i,cnt = 0;
                while (!bo[j])
                {
                    bo[j] = true;
                    cnt++;
                    j = a[j];
                }
                v.pb(cnt);
            }
        int len = v.size();
        rep1(i,0,len-1)
        {
            int now = 2,x = v[i],ii = 0,len2 = zhi.size();
            while (ii<=len2-1 && now<=x)
            {
                now = zhi[ii];
                if (x%now==0)
                {
                    int cnt = 0;
                    while (x%now==0)
                    {
                        cnt++;
                        x/=now;
                    }
                    if (num[now]==0)
                    {
                        num[now] = cnt;
                        what.pb(now);
                    }
                    else
                        num[now] = max(num[now],cnt);
                }
                ii++;
            }
        }
        al = 1;
        ans[1] = 1;
        len = what.size();
        rep1(i,0,len-1)
        {
            int len2 = num[what[i]];
            rep1(j,1,len2)
            {
                int x = 0;
                rep1(k,1,al)
                {
                    ans[k]= ans[k]*what[i]+x;
                    x = ans[k]/10;
                    ans[k] = ans[k]%10;
                }
                while (x>0)
                {
                    al++;
                    ans[al] = x;
                    x = ans[al]/10;
                    ans[al] = ans[al]%10;
                }
            }
        }
        rep2(i,al,1)
            printf("%d",ans[i]);
        return 0;
    }
  • 相关阅读:
    解决CentOS6.5虚拟机克隆后无法上网(网卡信息不一致)的问题
    Linux密码保护
    破解Linux系统开机密码
    Linux常用命令
    人教版中小学教材电子版下载
    作业一
    实验四
    实验一
    实验三
    实验二
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626638.html
Copyright © 2011-2022 走看看