优化-T2078 HKE与他的小朋友

题目链接:https://www.luogu.org/problemnew/show/T2078
题目背景

HKE带着nn个小朋友做游戏

题目描述

现在有n个座位编号为11至nn,这些小朋友也编号11至nn。一开始所有小朋友都坐在相应的座位上。HKE的游戏可用一个n的排列A(A_1,A_2\cdots _nA(A 1​ ,A 2​ ⋯A n​ )表示。一轮游戏时,对于所有的1\leq i\leq n1≤i≤n,坐在位置ii上的小朋友坐到位置A_iA i​ 上。

现在游戏进行了kk轮,HKE想知道游戏结束后,位置1,2\cdots n1,2⋯n分别坐了几号小朋友?

输入输出格式

输入格式:
第一行n,kn,k。

第二行A_1,A_2\cdots A_nA 1​ ,A 2​ ⋯A n

输出格式:
一行n个数表示位置1,2……n1,2……n上的小朋友的编号

输入输出样例

输入样例#1: 复制
5 5
2 3 1 5 4
输出样例#1: 复制
2 3 1 5 4
输入样例#2: 复制
5 4
2 3 1 5 4
输出样例#2: 复制
3 1 2 4 5
说明

30%的数据,n\leq1000n≤1000,k\leq1000k≤1000
100%的数据,n\leq100000n≤100000,k\leq2^{31}-1k≤2
31
−1

一开始打了个30分代码如下:

#include<iostream>
#include <algorithm>
using namespace std;

int k,n,a[100010],b[100010],c[100010];

int main()
{
	cin>>n>>k;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[i]=i;
	}
	
	for (int i=1;i<=k;i++)
	{
		for (int j=1;j<=n;j++)
		{
			c[a[j]]=b[j];
		}
		for (int j=1;j<=n;j++)
		{
			b[j]=c[j];
			cout<<b[j]<<" ";
		}
		cout<<endl; 
	}
	
//	for (int j=1;j<=n;j++)
//	{
//			cout<<b[j]<<" ";
//	}
		
    return 0;
}

大神给了个AC代码如下,仰望大神啊。

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int A[100001];
    int s[100001],t[100001];
    long long n,k;
	long long m,p,q,r;
      
    cin >> n >> k;
    
    for(long long i=1;i<=n;i++){
        cin >> A[i];
        s[i]=0;
    }
    
    for(long long i=1;i<=n;i++){
    	
		if(s[i]>0) continue;
    	
    	m=0;
    	p=i;
    	t[0]=i;
    	do{//计算单个数重复周期 
    		p=A[p];
    		m++;
			t[m]=p;
		}while(p!=i);
		q=k%m;
		p=i;
		do{//全环设置 
			r=t[q];
			s[r]=p;
			p=A[p];
			q++;
			q=q%m;
		}while(p!=i);

	}
    
    for(long long i=1;i<=n;i++){
        cout << s[i] << " ";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43126361/article/details/83930529
今日推荐