[cf] Codeforces Round #595 (Div. 3) B12 Books Exchange

前言

t a g : tag : tag:*1300 交换 思维 经典好题
传送门 :

题意 :
多组数据,每个人手上都有一本书,对于每个 a [ i ] a[i] a[i]表示将该书传给 a [ i ] a[i] a[i]个人。输出每个人需要多少次才可以拿到自己的书

思路 :
首先这种交换问题有很多变式,同时也非常经典,因为最终都是回到本身

因此不难发现 , 如果把交换过程进行连线, 那么能交换的 必然成一个

然而环中每个数再次轮到本身就是环的大小

因为每个环都只是遍历一次,环中的节点也只遍历一次,所以时间复杂度 O ( T ∗ n ) O(T*n) O(Tn)

这里给出两种写法

code :

int n;
int nx[N];
int st[N];
int ans[N];

void solve(){
	cin>>n;
	
	for(int i = 0 ;i < n ;i ++ )st[i] = 0, ans[i] = 0 ;
	for(int i = 0 ;i<n; i ++){
		cin>>nx[i];
		nx[i] --;
	}
	
	
	for(auto x :  nx){
		vector<int> v;
		while(!st[x]){
			v.pb(x);
			st[x] = 1;
			x =  nx[x];
		}
		
		for(auto y : v){
			ans[y] = v.size();
		}
	}
	
	for(int i = 0 ;i<n;i ++ )
	cout<<ans[i]<<" ";
	cout<<endl;
	

}

int main(){
    int t;cin>>t;while(t--)
    solve();
    return 0 ;
}
int n;
int a[N];
int st[N];
int sz[N];
int b[N];
vector<int> v[N];

void solve(){
	
	cin>>n;
	for(int i = 0 ; i<= n; i ++ ){
		st[i] = 0 , sz[i] = 0 ;
		v[i].clear();
	}
	
	int cnt  =0  ;
	
	for(int i = 1; i <= n ;i ++ ) cin>>a[i];
	
	for(int i = 1; i <= n ;i ++ ){
		if(st[i]) continue;
		
		for(int j = i;;j=a[j]){
			if(st[j]){
				cnt++;
				break;
			}
			v[cnt].pb(j);
			sz[cnt]++;
			st[j] =  1;
		}
	}
	
	for(int i = 0;i<cnt;i ++ ){
		for(auto x : v[i]){
			b[x] = sz[i];
		}
	} 
	
	for(int i = 1; i <= n ;i ++ ) cout<<b[i]<<" ";
	cout<<endl;

}

int main(){
    int t;cin>>t;while(t--)
    solve();
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值