大家春节快乐。最近过年,堕落了好几天,今天随便a了一道数论的题,聊当练手。题意是说要找一个置换的阶,所以当我们把这个置换的形式写出后找出其所有子置换的最小公倍数即可。另外最近在重新练手,练习科学c++的写法,请大家多加指教。
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
#define MAXN 1004
class Permutation
{
private:
int _permuArray[MAXN];
vector<int > _singlePermus[MAXN];
int _size;
int _permuPointer;
bool _visited[MAXN];
set<int > _allLengths;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
int lcm(int a, int b) { return a*b / gcd(a, b); }
public:
Permutation(){}
void analyze()
{
memset(_visited, 0, sizeof(_visited));
for (int i = 0; i < _size; i++)
_singlePermus[i].clear();
_permuPointer = 0;
for (int i = 1; i <= _size; i++) {
if (_visited[i]||_permuArray[i]==i)
continue;
_visited[i] = true;
_singlePermus[_permuPointer].push_back(i);
int j = _permuArray[i];
while (j != i) {
_singlePermus[_permuPointer].push_back(j);
_visited[j] = true;
j = _permuArray[j];
}
_permuPointer++;
}
_allLengths.clear();
for (int i = 0; i < _permuPointer; i++)
_allLengths.insert(_singlePermus[i].size());
}
void calculateOrder()
{
int times = 1;
set<int >::iterator it;
for (it = _allLengths.begin(); it != _allLengths.end(); it++)
times = lcm(times, *it);
//printf("Order:%d\n", times);
printf("%d\n", times);
}
Permutation(int size)
{
_size = size;
memset(_permuArray, 0, sizeof(_permuArray));
for (int i = 1; i <= _size; i++)
scanf("%d", &_permuArray[i]);
}
void show()
{
for (int i = 1; i <= _size; i++)
printf("%d\t", _permuArray[i]);
printf("\n");
for (int i = 0; i < _permuPointer; i++) {
for (int j = 0; j < _singlePermus[i].size(); j++)
printf("%d ", _singlePermus[i][j]);
printf("\n");
}
set<int >::iterator it;
for (it = _allLengths.begin(); it != _allLengths.end(); it++)
printf("%d\t", *it);
printf("\n");
}
};
int Size;
int main()
{
Permutation p;
while (scanf("%d", &Size) != EOF) {
p = Permutation(Size);
p.analyze();
//p.show();
p.calculateOrder();
}
}