0
点赞
收藏
分享

微信扫一扫

重新排列奶牛(春季每日一题 33)

农夫约翰的 重新排列奶牛(春季每日一题 33)_环图 头奶牛排成一排,编号 重新排列奶牛(春季每日一题 33)_循环移位_02

它们的排序可以由一个数组 重新排列奶牛(春季每日一题 33)_环图_03 来描述,其中 重新排列奶牛(春季每日一题 33)_i++_04 是位于位置 重新排列奶牛(春季每日一题 33)_i++_05 的奶牛的编号。

约翰希望将它们重新排列为一个不同的顺序。

新顺序用数组 重新排列奶牛(春季每日一题 33)_i++_06 来描述,其中 重新排列奶牛(春季每日一题 33)_并查集_07 是位于位置 重新排列奶牛(春季每日一题 33)_i++_05 的奶牛的编号。

假设奶牛开始时的顺序为:

A = 5 1 4 2 3

并假设约翰希望它们重新排列为:

B = 2 5 3 1 4

为了从 重新排列奶牛(春季每日一题 33)_环图_03 顺序重新排列为 重新排列奶牛(春季每日一题 33)_i++_06 顺序,奶牛们进行了许多“循环”移位。

所谓循环移位,是指挑选排列中的若干头奶牛分在一组,组中奶牛进行循环移动位置,即第一头奶牛移动至第二头奶牛的位置,第二头奶牛移动至第三头奶牛的位置,…,最后一头奶牛移动至第一头奶牛的位置。

如上例中,将 重新排列奶牛(春季每日一题 33)_循环移位_11 号奶牛分在一组进行循环移位,移动过后,重新排列奶牛(春季每日一题 33)_循环移位_12 号奶牛移动至位置 重新排列奶牛(春季每日一题 33)_找环_13 号奶牛移动至位置 重新排列奶牛(春季每日一题 33)_找环_14 号奶牛移动至位置 重新排列奶牛(春季每日一题 33)_找环_15;将 重新排列奶牛(春季每日一题 33)_循环移位_16 号奶牛分在另一组进行循环移位,移动过后,重新排列奶牛(春季每日一题 33)_并查集_17 号奶牛位于位置 重新排列奶牛(春季每日一题 33)_找环_18 号奶牛位于位置 重新排列奶牛(春季每日一题 33)_循环移位_19;最终完成重新排列。

每头奶牛都恰好参与一组循环移位,除非其在 重新排列奶牛(春季每日一题 33)_环图_20 中的位置没有变化。

请计算奶牛们完成重新排列,共需多少组循环移位,最长的一组循环移位的长度是多少。

输入格式
第一行包含整数 重新排列奶牛(春季每日一题 33)_环图

接下来 重新排列奶牛(春季每日一题 33)_环图 行包含 重新排列奶牛(春季每日一题 33)_i++_04

再接下来 重新排列奶牛(春季每日一题 33)_环图 行包含 重新排列奶牛(春季每日一题 33)_并查集_07

输出格式
输出循环移位的组数,以及最长的一组循环移位的长度。

如果不存在循环移位,则第二个数输出 重新排列奶牛(春季每日一题 33)_环图_26

数据范围
重新排列奶牛(春季每日一题 33)_i++_27
重新排列奶牛(春季每日一题 33)_环图_28

输入样例:

5
5
1
4
2
3
2
5
3
1
4

输出样例:

2 3
#include<iostream>

using namespace std;

const int N = 110;

int n;
int a[N], b[N], bid[N];
int p[N], cnt[N];

int find(int x){

if(x != p[x]) p[x] = find(p[x]);
return p[x];
}

int main(){

for(int i = 1; i < N; i++) p[i] = i;

cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) cin >> b[i];

for(int i = 1; i <= n; i++){

int px = find(a[i]), py = find(b[i]);
if(px != py) p[px] = py;
}

for(int i = 1; i <= n; i++){
cnt[find(i)]++;
}

int r1 = 0, r2 = 0;
for(int i = 1; i <= n; i++) r2 = max(r2, cnt[i]), r1 += (cnt[i] > 1);

if(r2 == 1) r2 = -1;

cout << r1 << ' ' << r2;

return 0;
}


举报

相关推荐

0 条评论