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

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

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

需要注意的是:

执行命令是从右往左执行的,这是题目中说的=_=

其他命令还好,mix那个命令把我搞得晕头转向,题中给的是反的,我们要反过来求原图像(i, j)在新图像中的位置。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std; int gcd(int a, int b)
{ return b == ? a : gcd(b, a%b); } int lcm(int a, int b)
{ return a / gcd(a, b) * b; } const int maxn = ;
int n;
char s[], op[][]; inline int ID(int i, int j)
{ return i*n + j; } int newpos(int i, int j, const char* op)
{
if(op[] == 'r') return ID(n-j-, i);
if(op[] == 's') return ID(i, n-j-);
if(op[] == 'b' && op[] == 'h')
{
if(i >= n/) return ID(i, n-j-);
return ID(i, j);
}
if(op[] == 'b' && op[] == 'v')
{
if(i >= n/) return ID(n-(i-n/)-, j);
return ID(i, j);
}
if(op[] == 'd')
{
if(i & ) return ID(n/ + i/ ,j);
return ID(i/, j);
}
if(op[] == 'm')
{
int k = i/;
if(j < n/) return i % == ? ID(k*, j*) : ID(k*, j*+);
else return i % == ? ID(*k+, *(j-n/)) : ID(*k+, *(j-n/)+);
}
return ID(i, j);
} int cur[maxn * maxn], origin[maxn * maxn]; void apply(const char* op)
{
for(int i = ; i < n*n; i++) origin[i] = cur[i];
bool inv = op[strlen(op)-] == '-' ? true : false;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++)
{
int p = ID(i, j), p2 = newpos(i, j, op);
if(inv) cur[p] = origin[p2];
else cur[p2] = origin[p];
}
} bool vis[maxn * maxn]; int solve()
{
memset(vis, false, sizeof(vis));
int ans = ;
for(int i = ; i < n*n; i++) if(!vis[i])
{
int cnt = , j = i;
do
{
vis[j] = ;
cnt++;
j = cur[j];
}while(j != i);
ans = lcm(cnt, ans);
}
return ans;
} int main()
{
//freopen("in.txt", "r", stdin); int T;
scanf("%d", &T);
for(int kase = ; kase < T; kase++)
{
if(kase) puts(""); scanf("%d", &n); getchar();
string line, temp;
getline(cin, line);
stringstream ss(line);
vector<string> op;
while(ss >> temp) op.push_back(temp); for(int i = ; i < n*n; i++) cur[i] = i;
for(int i = op.size() - ; i >= ; i--) apply(op[i].c_str());
printf("%d\n", solve());
} return ;
}

代码君

LA 3510 (置换 循环分解) Pixel Shuffle的更多相关文章

  1. LA 3641 (置换 循环的分解) Leonardo's Notebook

    给出一个26个大写字母的置换B,是否存在A2 = B 每个置换可以看做若干个循环的乘积.我们可以把这些循环看成中UVa 10294的项链, 循环中的数就相当于项链中的珠子. A2就相当于将项链旋转了两 ...

  2. UVA 1156 - Pixel Shuffle(模拟+置换)

    UVA 1156 - Pixel Shuffle 题目链接 题意:依据题目中的变换方式,给定一串变换方式,问须要运行几次才干回复原图像 思路:这题恶心的一比,先模拟求出一次变换后的相应的矩阵,然后对该 ...

  3. UVALive - 3510 Pixel Shuffle (置换)

    题目链接 有一个n*n的图像和7种置换,以及一个置换序列,求将这个序列重复做几次能得到原图像. 将这些置换序列乘起来可得到一个最终置换,这个置换所有循环节的长度的lcm即为答案. 注意置换是从右往左进 ...

  4. UVa 11330 (置换 循环的分解) Andy's Shoes

    和UVa11077的分析很类似. 我们固定左脚的鞋子不动,然后将右脚的鞋子看做一个置换分解. 对于一个长度为l的循环节,要交换到正确位置至少要交换l-1次. #include <cstdio&g ...

  5. UVa 11077 (循环分解 递推) Find the Permutations

    把{1, 2, 3,,, n}叫做自然排列 本题便是求有多少个n元排列P要至少经过k次交换才能变为自然排列. 首先将排列P看做置换,然后将其分解循环,对于每个长度为i的循环至少要交换i-1次才能归位. ...

  6. LA3510 Pixel Shuffle

    题意 PDF 分析 思路挺简单的,题目中的每个命令(包括命令的逆)相当于一个置换. 用\(O(n^2k)\)的时间复杂度从右往左求出这些置换的乘积A,然后求m使Am = I(I为全等置换) 还是先把A ...

  7. Leonardo的笔记本LA 3641——置换的乘法

    题意 给出26个大写字母的置换 $B$,问是否存在一个置换 $A$,使得 $A^2=B$. 分析 首先,若A=BC,若B和C都能表示成两个相同循环的乘积,则A也能. 因为,不相交的循环的乘积满足交换律 ...

  8. for 循环分解

    for (expression1; expression2; expression3) { statement; } statement称为循环体 expression1为初始化部分,只在循环开始前执 ...

  9. poj 3270(置换 循环)

    经典的题目,主要还是考思维,之前在想的时候只想到了在一个循环中,每次都用最小的来交换,结果忽略了一种情况,还可以选所有数中最小的来交换一个循环. Cow Sorting Time Limit: 200 ...

随机推荐

  1. 用C#进行WinForm开发对数据库的相关操作

    class SQLHelper { public SqlConnection conn; //<summary> //链接.打开数据库 //</summary> public ...

  2. sqlserver oracle 时间加减

    sqlserver: 减去10小时: dateadd(hour,-10,Your_date) oracle : 减去10小时: sysdate()-10/24

  3. javascript小实例,PC网页里的拖拽(转)

    这是现在的效果,可能改了一些,原来的效果是,里面的这张图是可以上下左右拖动的,然后房子上面的显示的楼栋号,也跟着图片一起移动,当时js能力还不行,未能实现项目经理的要求,不过后来项目经理又把这个效果推 ...

  4. java递归查询方法

    一.需求 项目里要让用户能够设置所选择教材的章课节,以针对章课节提供相应的题目供用户做题. 设计:用户设置了教材后,首次登录,进行章节设置时.默认为用户选择第一章.第一课.第一节. 思路:用户访问页面 ...

  5. windows 下c++编译

    http://blog.csdn.net/dyllove98/article/details/9314993

  6. web系统之session劫持解决

    session劫持是一种比较复杂的攻击方法.大部分互联网上的电脑多存在被攻击的危险.这是一种劫持tcp协议的方法,所以几乎所有的局域网,都存在被劫持 可能. 两台主机要想进行TCP通信,必须经过一个三 ...

  7. CC150 上面重要的题目总结

    第一章 : 全部重要 (1.6, 1.7 Leetcode上有). 1.5 面A碰到 (string compression) 1.7面Z碰到 (set 0) 1.8面Bigfish碰到 (strin ...

  8. SDUT1061Binomial Showdown(组合数)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1061 题意 : 表示这个题的英文没看懂,就看懂 ...

  9. *[codility]CartesianSequence

    https://codility.com/programmers/challenges/upsilon2012 求笛卡尔树的高度,可以用单调栈来做. 维持一个单调递减的栈,每次进栈的时候记录下它之后有 ...

  10. Linux之SAMBA共享服务

    简述 Samba服务器可以让Windows操作系统用户访问局域网中Linux主机,就象访问网上邻居一样方便. 具有以下功能: 共享目录:在局域网上共享某个或某些目录,使得同一个网络内的Windows用 ...