UVALive - 3510 Pixel Shuffle (群论)

题意:对一张像素图可以执行旋转、翻转、div、mix等操作,现在给出一个操作序列,问重复进行多少次这个操作序列,可以使得任意n*n的像素图变回原样。

转换一下就是:设操作序列为置换A,则求m使得A^m为全等置换(所有元素都映射到自己)

对于每个长度为L的循环B,当m为B的整数倍时,B^m为全等置换,所以只需要把操作序列对应的置换拆解成多个循环,求每个循环长度的LCM即可,然后题目就变成了模拟。

(我的mix_竟然能写超时。。。就是代码中的imix1,换了个写法就过了)

#include <bits/stdc++.h>
#include<cstdio>
#include<cstring>
using namespace std;
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define mp make_pair
typedef long long ll;
const int maxn=10005;
const int maxm=1e5+15;
const int maxe=200005;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
int n,m;
int id[1050][1050];
int cnt[1050][1050];
bool vis[1050][1050];
inline int idx(int x,int y){
    return x*n+y;
}
char str[1050];
ll k,ggg;
void cop(){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            id[i][j]=cnt[i][j];
        }
    }
}

void imix(){
    for(int i=0;i<n;i+=2){
        for(int j=0;j<n/2;j++){
                cnt[i][j]=id[i][j*2];
                cnt[i+1][j]=id[i][j*2+1];
                cnt[i][n/2+j]=id[i+1][j*2];
                cnt[i+1][n/2+j]=id[i+1][j*2+1];
        }
    }
    cop();
}

void imix1(){
    for(int i=0;i<n;i++){
        int k2=i/2*2;
        for(int j=0;j<n;j++){
            if(i&1){
                for(int j=0;j<n;j++){
                    int cc=n/2+j/2;
                    if(j&1){
                        cnt[k2+1][cc]=id[i][j];
                    }
                    else cnt[k2][cc]=id[i][j];
                }
            }
            else{
                int cc=j/2;
                if(j&1){
                    cnt[k2+1][cc]=id[i][j];
                }
                else{
                    cnt[k2][cc]=id[i][j];
                }
            }
        }
    }
    cop();
}

void mix(){
    for(int i=0;i<n;i++){
        int k2=i/2*2;
        if(i&1){
            for(int j=0;j<n;j++){
                int cc=n/2+j/2;
                if(j&1){
                    cnt[i][j]=id[k2+1][cc];
                }
                else cnt[i][j]=id[k2][cc];
            }
        }
        else{
            for(int j=0;j<n;j++){
                int cc=j/2;
                if(j&1){
                    cnt[i][j]=id[k2+1][cc];
                }
                else{
                    cnt[i][j]=id[k2][cc];
                }
            }

        }
    }
    cop();
}

void idiv(){
    int cc=-1;
    for(int i=0;i<n;i+=2){
        cc++;
        for(int j=0;j<n;j++){
            cnt[i][j]=id[cc][j];
        }
    }
    cc=n/2-1;
    for(int i=1;i<n;i+=2){
        cc++;
        for(int j=0;j<n;j++){
            cnt[i][j]=id[cc][j];
        }
    }
    cop();
}

void div(){
    for(int i=0;i<n/2;i++){
        for(int j=0;j<n;j++){
            cnt[i][j]=id[i*2][j];
        }
    }
    int cc=-1;
    for(int i=n/2;i<n;i++){
        cc+=2;
        for(int j=0;j<n;j++){
            cnt[i][j]=id[cc][j];
        }
    }
    cop();
}

void bvsm(){
    for(int i=0;i<n/4;i++){
        for(int j=0;j<n;j++){
            swap(id[n/2+i][j],id[n-1-i][j]);
        }
    }
}

void bhsym(){
    for(int i=n/2;i<n;i++){
        for(int j=0;j<n/2;j++){
            swap(id[i][j],id[i][n-1-j]);
        }
    }
}

void sym(){
    for(int i=0;i<n;i++)
    for(int j=0;j<n/2;j++){
        swap(id[i][j],id[i][n-1-j]);
    }
}

void rot(){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cnt[i][j]=id[j][n-1-i];
        }
    }
    cop();
}

void irot(){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cnt[i][j]=id[n-1-j][i];
        }
    }
    cop();
}

void calc(int lef,int rig){
    if(lef>=rig)return;
    if(str[lef]=='i')return;
    else if(str[lef]=='r'){
        if(str[rig]=='-')irot();
        else rot();
    }
    else if(str[lef]=='s')sym();
    else if(str[lef]=='b'){
        if(str[lef+1]=='h'){
            bhsym();
        }
        else{
            bvsm();
        }
    }
    else if(str[lef]=='d'){
        if(str[rig]=='-')idiv();
        else div();
    }
    else{
        if(str[rig]=='-')imix();
        else mix();
    }
}

void print(){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%d\t",id[i][j]);
        }
        printf("\n");
    }
    puts("");
}

ll gcd(ll a,ll b){
    if(b==0)return a;
    return gcd(b,a%b);
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                id[i][j]=idx(i,j);
            }
        }
        getchar();
        gets(str);
        m=strlen(str);
        int last=m-1,cc=m-1;
       //print();
        for(int cc=m-1;cc>=0;cc--){
            if(str[cc]==' '||cc==0){
                if(cc==0)calc(cc,last);
                else calc(cc+1,last);
          //      print();
                last=cc-1;
            }
        }
        ggg=0;
        k=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(vis[i][j])continue;
                int cntx=i,cnty=j;
                int cc=0;
                while(vis[cntx][cnty]==0){
                    vis[cntx][cnty]=1;
                    int val=id[cntx][cnty];
                    cntx=val/n;
                    cnty=val%n;
                    cc++;
                }
                k*=(cc/gcd(k,cc));
            }
        }
        printf("%lld\n",k);
        if(T)printf("\n");
    }
    return 0;
}


/*
1
1024
mix- mix- mix- mix- mix- mix- mix- mix- mix- mix- mix- mix-

mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix mix


id id- rot rot- sym sym- bhsym bhsym- bvsm bvsm- div div- div div-
id id- rot rot- sym sym- bhsym bhsym- bvsm bvsm- div div- mix mix-
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值