您的位置:首页 > 其它

Pixel Shuffle [Poj 2789,CERC 2005/SWERC 2005,LA 3510]

2016-06-10 09:49 609 查看
题目地址请点击——

Pixel Shufflent

Description

在一个 n×n(n 为偶数) 的黑白位图上反复执行同一个像素混和序列,问重复做几次后会得到原图像?

每个混合序列是由若干个混合命令组成,这些命令如下。

id:不变

rot:逆时针旋转 90°

sym:水平翻转

bhsym:下一半的图像水平翻转

bvsym:下一半图像垂直翻转

div:第 0,2,4,…n−2 行变成第 0,1,2,…,n/2−1 行,第 1,3,5,…,n−1 行变成第 n/2,n/2+1,…n−1 行

mix:行混合。

新图像的第 2k 行依次是原图像的 (2k,0),(2k+1,0),(2k,1),(2k+1,1),…,(2k,n2−1),(2k+1,n2−1) 这些像素。

第 2k+1 行依次是原图像的 (2k,n2),(2k+1,n2),(2k,n2+1),(2k+1,n2+1),…,(2k,n−1),(2k+1,n−1)

对字母 A 使用这 7 种混合法后的效果如图所示。



Input

第一行为位图边长 n (2≤n≤210),第二行为不超过 k(k≤32)个混合命令。

如果一个命令后面有一个减号“-”,表示应该执行该命令的逆。

命令从右往左执行。

Output

输出最小重复次数。

Sample Input 1

256

rot- div rot div

Sample Output 1

8

Sample Input 2

256

bvsym div mix

Sample Output 2

63457

Solution

每一个操作可视为一个置换,将这些置换的成绩循环分解,然后答案就为所有循环的元素个数的最小公倍数。

Code

#include <iostream>
#include <cstdio>
#include <cstring>

#define PLA(x,y) PLAS[(x)][(y)]

using namespace std;

char input[100000];
int T,n,cnt;
int row[100000];
int to[1300000];
bool vis[1300000];
int PLAS[2000][2000];
int nxt[1300000];

int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}

void work(int x){
switch(x){
case 9:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
nxt[PLA(i,j)]=to[PLA(j,n-i-1)];
break;
case 3:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
nxt[PLA(i,j)]=to[PLA(i,n-j-1)];
break;
case 4:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i>=n/2)nxt[PLA(i,j)]=to[PLA(i,n-j-1)];
break;
case 5:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i>=n/2)nxt[PLA(i,j)]=to[PLA(n/2+n-1-i,j)];
break;
case 7:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(!((i)&1))nxt[PLA(i,j)]=to[PLA(i+((j)&1),(j)/2)];
else nxt[PLA(i,j)]=to[PLA(i+((j)&1)-1,(j)/2+n/2)];
}
break;
case 2:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
nxt[PLA(i,j)]=to[PLA(n-j-1,i)];
break;
case 6:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i<n/2)nxt[PLA(i,j)]=to[PLA((i)*2,j)];
else nxt[PLA(i,j)]=to[PLA(2*(i-n/2)+1,j)];
break;
case 13:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(!((i)&1))nxt[PLA(i,j)]=to[PLA(i/2,j)];
else nxt[PLA(i,j)]=to[PLA(i/2+n/2,j)];
break;
case 14:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(j<n/2){
if(!((i)&1))nxt[PLA(i,j)]=to[PLA(i,(j)*2)];
else nxt[PLA(i,j)]=to[PLA(i-1,(j)*2+1)];
}
else{
if(!((i)&1))nxt[PLA(i,j)]=to[PLA(i+1,(j-n/2)*2)];
else nxt[PLA(i,j)]=to[PLA(i,(j-n/2)*2+1)];
}
}
break;
default:break;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
to[PLA(i,j)]=nxt[PLA(i,j)];
}

int main(){

scanf("%d",&n);gets(input);if((input[0]<'a'||input[0]>'z')&&(input[0]<'A'||input[0]>'Z'))gets(input);

for(int i=0;i<n;i++)
for(int j=0;j<n;j++)PLAS[i][j]=((i)*n+(j)+1);

int l=strlen(input);cnt=0;

int end=PLA(n-1,n-1);
for(int i=1;i<=end;i++)to[i]=nxt[i]=i;

for(int i=0;i<=l;i++){
if(input[i]==' '||i==l){
switch(input[i-1]){
case 'd':continue;
case 't':row[++cnt]=2;break;
case 'v':row[++cnt]=6;break;
case 'x':row[++cnt]=7;break;
case 'm':
if(i>3&&input[i-4]=='h')row[++cnt]=4;
else if(i>3&&input[i-4]=='v')row[++cnt]=5;
else row[++cnt]=3;
break;
case '-':
switch(input[i-2]){
case 'd':continue;
case 't':row[++cnt]=9;break;
case 'v':row[++cnt]=13;break;
case 'x':row[++cnt]=14;break;
case 'm':
if(i>4&&input[i-5]=='h')row[++cnt]=4;
else if(i>4&&input[i-5]=='v')row[++cnt]=5;
else row[++cnt]=3;
break;
default:break;
}
break;
default:break;
}
}
}

for(int i=cnt;i>=1;i--)work(row[i]);

int ans=1;
for(int i=1;i<=end;i++)if(!vis[i]){
int j=i,tot=0;
do{
vis[j]=true;
tot++;
j=to[j];
}while(i!=j);
ans=ans/gcd(ans,tot)*tot;
}
printf("%d",ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: