UVALive

题目链接

有一个n*n的图像和7种置换,以及一个置换序列,求将这个序列重复做几次能得到原图像。

将这些置换序列乘起来可得到一个最终置换,这个置换所有循环节的长度的lcm即为答案。

注意置换是从右往左进行的,开始没仔细读题,debug到崩溃~~

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned long long ll;
 4 const int N=1024+10;
 5 typedef vector<int> Per;
 6 Per operator*(const Per& a,const Per& b) {
 7     Per c(a.size());
 8     for(int i=0; i<c.size(); ++i)c[i]=b[a[i]];
 9     return c;
10 }
11 Per inv(const Per& a) {
12     Per c(a.size());
13     for(int i=0; i<c.size(); ++i)c[a[i]]=i;
14     return c;
15 }
16 Per a[10][2];
17 int n,k,ka;
18 int f(int i,int j) {return i*n+j;}
19 string line;
20 int vis[N*N];
21 ll lcm(ll a,ll b) {return a/__gcd(a,b)*b;}
22 int main() {
23     int T;
24     for(scanf("%d",&T); T--;) {
25         !ka?++ka:puts("");
26         scanf("%d ",&n);
27         for(int i=0; i<7; ++i)a[i][0].resize(n*n);
28         for(int i=0; i<n; ++i)
29             for(int j=0; j<n; ++j) {
30                 a[0][0][f(i,j)]=f(i,j);
31                 a[1][0][f(i,j)]=f(n-1-j,i);
32                 a[2][0][f(i,j)]=f(i,n-1-j);
33                 a[3][0][f(i,j)]=i<n/2?f(i,j):f(i,n-1-j);
34                 a[4][0][f(i,j)]=i<n/2?f(i,j):f(n-1-i+n/2,j);
35                 a[5][0][f(i,j)]=i&1?f(i/2+n/2,j):f(i/2,j);
36                 a[6][0][f(i,j)]=i&1?f(i-(j&1^1),j/2+n/2):f(i+(j&1),j/2);
37             }
38         for(int i=0; i<7; ++i)a[i][1]=inv(a[i][0]);
39         swap(a[6][0],a[6][1]);
40         Per p=a[0][0];
41         getline(cin,line);
42         stringstream ss(line);
43         string s;
44         while(ss>>s) {
45             int t=0;
46             if(s.back()=='-')t=1,s.pop_back();
47             if(s=="id")p=a[0][t]*p;
48             else if(s=="rot")p=a[1][t]*p;
49             else if(s=="sym")p=a[2][t]*p;
50             else if(s=="bhsym")p=a[3][t]*p;
51             else if(s=="bvsym")p=a[4][t]*p;
52             else if(s=="div")p=a[5][t]*p;
53             else if(s=="mix")p=a[6][t]*p;
54         }
55         memset(vis,0,sizeof vis);
56         ll ans=1;
57         for(int i=0; i<p.size(); ++i)if(!vis[i]) {
58                 ll cnt=1;
59                 vis[i]=1;
60                 for(int j=p[i]; j!=i; vis[j]=1,j=p[j])++cnt;
61                 ans=lcm(ans,cnt);
62             }
63         printf("%lld
",ans);
64     }
65     return 0;
66 }
原文地址:https://www.cnblogs.com/asdfsag/p/11434591.html