UVa 1156 Pixel Shuffle(置换)

Posted 7391_KID

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 1156 Pixel Shuffle(置换)相关的知识,希望对你有一定的参考价值。

链接:https://vjudge.net/problem/UVA-1156

题目大意:给定一个n*n的像素图,有若干种操作将图做一个映射,给定若干映射,求至少反复做这些映射多少次,能得到原图。

分析:将图看做一个n^2*1的向量,每种操作就是一种置换,求出给的置换的乘积M,然后将M分解为正交的若干置换的乘积,答案就是这些置换的长度的最小公约数。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<string>
  5 using namespace std;
  6 typedef long long ll;
  7 const int maxn=(1<<20)+5;
  8 int rot[maxn],sym[maxn],bhs[maxn],bvs[maxn],Div[maxn],mix[maxn];
  9 int n;
 10 void CalT(){
 11     for(int i=0;i<n*n;i++){
 12         int x=i/n,y=i%n;
 13         rot[i]=y*n+n-x-1;
 14     }
 15     for(int i=0;i<n*n;i++){
 16         int x=i/n,y=i%n;
 17         sym[i]=x*n+n-1-y;
 18     }
 19     for(int i=0;i<n*n/2;i++)bhs[i]=i;
 20     for(int i=n*n/2;i<n*n;i++){
 21         int x=i/n,y=i%n;
 22         bhs[i]=x*n+n-1-y;
 23     }
 24     for(int i=0;i<n*n/2;i++)bvs[i]=i;
 25     for(int i=n*n/2;i<n*n;i++){
 26         int x=i/n,y=i%n;
 27         bvs[i]=(n-1-x+n/2)*n+y;
 28     }
 29     for(int i=0;i<n*n/2;i++){
 30         int x=i/n,y=i%n;
 31         Div[i]=2*x*n+y;
 32     }
 33     for(int i=n*n/2;i<n*n;i++){
 34         int x=i/n,y=i%n;
 35         Div[i]=(2*(x-n/2)+1)*n+y;
 36     }
 37     for(int x=0;x<n;x+=2){
 38         for(int y=0;y<n/2;y++){
 39             mix[x*n+2*y]=x*n+y;
 40             mix[x*n+2*y+1]=(x+1)*n+y;
 41         }
 42     }
 43     for(int x=1;x<n;x+=2){
 44         for(int y=0;y<n/2;y++){
 45             mix[x*n+2*y]=(x-1)*n+y+n/2;
 46             mix[x*n+2*y+1]=x*n+y+n/2;
 47         }
 48     }
 49 }
 50 char p[500];
 51 int M[maxn],M0[maxn];
 52 void Copy(int *a,int *b,int n){
 53     for(int i=0;i<n;i++)a[i]=b[i];
 54 }
 55 void Mu_(int *a){
 56     for(int i=0;i<n*n;i++){
 57         M0[i]=M[a[i]];
 58     }
 59     Copy(M,M0,n*n);
 60 }
 61 void Mu(int *a){
 62     for(int i=0;i<n*n;i++){
 63         M0[a[i]]=M[i];
 64     }
 65     Copy(M,M0,n*n);
 66 }
 67 //void Print(){
 68 //    for(int i=0;i<n;i++){
 69 //        for(int j=0;j<n;j++){
 70 //            printf("%4d",M[i*n+j]);
 71 //        }
 72 //        cout<<endl;
 73 //    }
 74 //    cout<<"*******"<<endl;
 75 //}
 76 void GetM(){
 77     for(int i=0;i<n*n;i++)M[i]=i;
 78     int i=0,j=0,len=strlen(p);
 79     while(i<len){
 80         while(p[j]!= &&p[j]!=\0)j++;
 81         switch(p[i]){
 82         case r:
 83             if(p[j-1]==-)Mu_(rot);
 84             else Mu(rot);break;
 85         case s:
 86             if(p[j-1]==-)Mu_(sym);
 87             else Mu(sym);break;
 88         case b:
 89             if(p[i+1]==h){
 90                 if(p[j-1]==-)Mu_(bhs);
 91                 else Mu(bhs);
 92             }else{
 93                 if(p[j-1]==-)Mu_(bvs);
 94                 else Mu(bvs);
 95             }break;
 96         case d:
 97             if(p[j-1]==-)Mu_(Div);
 98             else Mu(Div);break;
 99         case m:
100             if(p[j-1]==-)Mu_(mix);
101             else Mu(mix);break;
102         default:break;
103         }
104 //        Print();
105         i=++j;
106     }
107 }
108 int gcd(int a,int b){
109     return a==0?b:gcd(b%a,a);
110 }
111 int lcm(int a,int b){
112     return (ll)a*b/gcd(a,b);
113 }
114 bool vis[maxn];
115 int Getlen(int u){
116     vis[u]=true;
117     int next=M[u],cnt=1;
118     while(next!=u){
119         vis[next]=true;
120         next=M[next];
121         cnt++;
122     }
123     return cnt;
124 }
125 int solve(){
126     int m=1;
127     memset(vis,0,sizeof(vis));
128     for(int i=0;i<n*n;i++){
129         if(vis[i])continue;
130         int q=Getlen(i);
131         m=lcm(m,q);
132     }
133     return m;
134 }
135 //void test(){
136 //    cin>>n;
137 //    CalT();
138 //    for(int i=0;i<n;i++){
139 //        for(int j=0;j<n;j++){
140 //            cin>>M[i*n+j];
141 //        }
142 //    }
143 //    Print();
144 //
145 //    cout<<"rot"<<endl;
146 //    Mu(rot);
147 //    Print();
148 //    Mu_(rot);
149 //    Print();
150 //
151 //    cout<<"sym"<<endl;
152 //    Mu(sym);
153 //    Print();
154 //    Mu_(sym);
155 //    Print();
156 //
157 //    cout<<"bhs"<<endl;
158 //    Mu(bhs);
159 //    Print();
160 //    Mu_(bhs);
161 //    Print();
162 //
163 //    cout<<"bvs"<<endl;
164 //    Mu(bvs);
165 //    Print();
166 //    Mu_(bvs);
167 //    Print();
168 //
169 //    cout<<"div"<<endl;
170 //    Mu(Div);
171 //    Print();
172 //    Mu_(Div);
173 //    Print();
174 //
175 //    cout<<"mix"<<endl;
176 //    Mu(mix);
177 //    Print();
178 //    Mu_(mix);
179 //    Print();
180 //}
181 int main(){
182 //    freopen("e:\\in.txt","r",stdin);
183 //    test();
184     int T;
185     scanf("%d",&T);
186     for(int kase=0;kase<T;kase++){
187         if(kase)printf("\n");
188         scanf("%d\n",&n);
189         cin.getline(p,500);
190         CalT();
191         GetM();
192         printf("%d\n",solve());
193     }
194     return 0;
195 }

 

以上是关于UVa 1156 Pixel Shuffle(置换)的主要内容,如果未能解决你的问题,请参考以下文章

UVA253 Cube painting置换

UVA - 11077 Find the Permutations (置换)

Uva 11077 Find the Permutations [置换群 DP]

UVA12174-Shuffle(滑动窗口)

UVA216 UVALive5155 Getting in Line置换+暴力

UVA - 10570 Meeting with Aliens (置换的循环节)