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(置换)的主要内容,如果未能解决你的问题,请参考以下文章
UVA - 11077 Find the Permutations (置换)
Uva 11077 Find the Permutations [置换群 DP]