zoukankan      html  css  js  c++  java
  • LA3510 Pixel Shuffle

    题意

    PDF

    分析

    思路挺简单的,题目中的每个命令(包括命令的逆)相当于一个置换。

    (O(n^2k))的时间复杂度从右往左求出这些置换的乘积A,然后求m使Am = I(I为全等置换)

    还是先把A分解循环,m则等于所有循环节长度的最小公倍数。

    代码

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
        while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    using namespace std;
    
    int gcd(int a,int b) {return b?gcd(b,a%b):a;}
    int lcm(int a,int b) {return a/gcd(a,b)*b;}
    #define ID(i,j) ((i)*n+(j))
    int newpos(int n,int i,int j,co char*op){
    	if(op[0]=='r') return ID(n-1-j,i); // rot
    	if(op[0]=='s') return ID(i,n-1-j); // sym
    	if(op[0]=='b'&&op[1]=='h') // bhsym
    		return i<n/2?ID(i,j):ID(i,n-1-j);
    	if(op[0]=='b'&&op[1]=='v') // bvsym
    		return i<n/2?ID(i,j):ID(n/2+n-i-1,j);
    	if(op[0]=='d')
    		return i%2==0?ID(i/2,j):ID(n/2+i/2,j);
    	if(op[0]=='m'){
    		int k=i/2;
    		if(j<n/2)
    			return i%2==0?ID(2*k,2*j):ID(2*k,2*j+1);
    		else
    			return i%2==0?ID(2*k+1,2*(j-n/2)):ID(2*k+1,2*(j-n/2)+1);
    	}
    	return assert(op[0]=='i'),ID(i,j);
    }
    
    co int N=1024;
    int orig[N*N];
    void apply(int*image,int n,co char*op){
    	bool inv=op[strlen(op)-1]=='-';
    	copy(image,image+n*n,orig);
    	for(int i=0;i<n;++i)for(int j=0;j<n;++j){
    		int p=ID(i,j),p2=newpos(n,i,j,op);
    		if(!inv) image[p2]=orig[p];
    		else image[p]=orig[p2];
    	}
    }
    
    int vis[N*N];
    int solve(int*p,int n){
    	fill(vis,vis+n,0);
    	int ans=1;
    	for(int i=0,j,len;i<n;++i)if(!vis[i]){
    		j=i,len=0;
    		do vis[j]=1,j=p[j],++len;
    		while(j!=i);
    		ans=lcm(ans,len);
    	}
    	return ans;
    }
    
    int cur[N*N];
    int main(){
    //	freopen(".in","r",stdin),freopen(".out","w",stdout);
    	int T,n,n2;
    	read(T),read(n);
    	for(;T--;n=n2){
    		for(int i=0;i<n*n;++i) cur[i]=i;
    		vector<string> ops;
    		for(int i=0;;++i){
    			static char op[10];
    			if(scanf("%s",op)==EOF) break;
    			if(isdigit(op[0])) {sscanf(op,"%d",&n2);break;}
    			ops.push_back(op);
    		}
    		for(int i=ops.size()-1;i>=0;--i)
    			apply(cur,n,ops[i].c_str());
    		printf("%d
    ",solve(cur,n*n));
    		if(T) puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    VIVADO固化
    Keil MDK 编译器 AC5 和 AC6 优化选项重要内容和区别
    STM32时钟
    STlink/v2中SWD模式连线方式
    搭载M33内核,支持最新蓝牙5.1,晚到的DA1469x生正逢时
    超全国内外蓝牙芯片原厂总结(含芯片型号)
    芯片封装类型大全
    国务院办公厅关于2012年部分节假日安排的通知
    美国摇滚乐队Metro致敬黄家驹,全粤语翻唱Beyond经典《海阔天空》
    国务院办公厅发布2010年部分节假日安排通知
  • 原文地址:https://www.cnblogs.com/autoint/p/10641962.html
Copyright © 2011-2022 走看看