acdream 1038: nanae is a good girl 置换群-循环因子
解题思路:
对于置换群 分解其循环因子
对于 需要对换一次,对于 需要对换两次, 所以当前置换群最少对换次数为三
对于 本题, 我们先 求出其 循环因子后,再从小到大 进行贪心即可
解题代码:
View Code
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> #include<algorithm> using namespace std; const int N = 100010; int a[N], b[N], n , k; bool vis[N]; int check(int s){ for( int i = s; i < n; i++) if( !vis[i] ) return i; return -1; } priority_queue< int,vector<int>, greater<int> > Q; int main() { while( scanf("%d%d", &n, &k ) != EOF ) { while( !Q.empty() ) Q.pop(); memset( vis, 0, sizeof(vis)); memset( b, 0, sizeof(b)); int cnt = 0, x, pos; for(int i = 0; i < n; i++) { scanf("%d", &x); a[i] = x; if( i == x ){ cnt++;vis[i] = true;} } pos = 0; while( (pos = check(pos) ) != -1 ){ int size = 0, t = pos; while( !vis[t] ) { size++; vis[t] = true; t = a[t]; } Q.push( size ); pos++; } while( !Q.empty() ){ int t = (Q.top()) - 1; Q.pop(); // printf("t = %d\n", t+1 ); if( t > k ){ cnt += k; break; } else { cnt += t+1; k -= t; } } printf("%d\n", cnt ); } return 0; }