AcWing 1921. 重新排列奶牛
题意
可以选择任意头奶牛,将他们进行循环移位,给定移位前的顺序和移位后的顺序,请计算奶牛们完成重新排列,共需多少组循环移位,最长的一组循环移位的长度是多少。
示例:
移位前:5 1 4 2 3
移位后:2 5 3 1 4
如上例中,将 5,1,2 号奶牛分在一组进行循环移位,移动过后,5 号奶牛移动至位置 2,1 号奶牛移动至位置 4,2 号奶牛移动至位置 1;将 4,3 号奶牛分在另一组进行循环移位,移动过后,4 号奶牛位于位置 5,3 号奶牛位于位置 3;最终完成重新排列。
数据范围
题解
注意环的长度为1的情况,不仅需要排除自环,还要排除单个的点,注意ans1和ans2的计数。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 110;
int a[N], b[N];
int e[N], ne[N], h[N], idx;
bool st[N];
int n;
void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int bfs(int x){
int res = 0;
queue<int> q;
q.push(x);
while(q.size()){
auto t = q.front();
q.pop();
//cout << t << ' ';
res ++;
for(int i = h[t]; i != -1; i = ne[i]){
int j = e[i];
if(st[j]) continue;
q.push(j);
st[j] = true;
}
}
//cout << '\n';
return res;
}
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i ++) scanf("%d", &a[i]);
for(int i = 0; i < n; i ++) scanf("%d", &b[i]);
memset(h, -1, sizeof h);
for(int i = 0; i < n; i ++) {
if(a[i] != b[i]) add(b[i], a[i]);
}
int ans1 = 0, ans2 = -1;
for(int i = 0; i < n; i ++){
if(!st[a[i]]){
st[a[i]] = true;
int t = bfs(a[i]);
if(t > 1) ans2 = max(ans2, t), ans1 ++;
}
}
printf("%d %d\n", ans1, ans2);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架