首页 > 代码库 > UVA - 1156 Pixel Shuffle (置换+模拟)
UVA - 1156 Pixel Shuffle (置换+模拟)
Description
Shuffling the pixels in a bitmap image sometimes yields random looking images. However, by repeating the shuffling enough times, one finally recovers the original images. This should be no surprise, since ``shuffling" means applying a one-to-one mapping (or permutation) over the cells of the image, which come in finite number.
Problem
Your program should read a number n , and a series of elementary transformations that define a ``shuffling" ofnxn images. Then, your program should compute the minimal numberm(m > 0) , such thatm applications of always yield the originalnxn image.
For instance if is counter-clockwise 90o rotation then m = 4 .
Input
The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
Input is made of two lines, the first line is number n (2n210 , n even). The number n is the size of images, one image is represented internally by anxn pixel matrix (aji) , where i is the row number andj is the column number. The pixel at the upper left corner is at row 0 and column 0.
The second line is a non-empty list of at most 32 words, separated by spaces. Valid words are the keywordsid, rot, sym, bhsym, bvsym,div and mix, or a keyword followed by ``-". Each keyword key designates an elementary transform (as defined by Figure 1), andkey- designates the inverse of transform key. For instance, rot- is the inverse of counter-clockwise 90o rotation, that is clockwise 90o rotation. Finally, the list k1, k2,..., kp designates the compound transform =k1ok2o ... okp . For instance, ``bvsym rot-" is the transform that first performs clockwise 90o rotation and then vertical symmetry on the lower half of the image.
Output
For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.
Your program should output a single line whose contents is the minimal number m(m > 0) such that is the identity. You may assume that, for all test input, you havem < 231 .
Sample Input
2 256 rot- div rot div 256 bvsym div mix
Sample Output
8 63457题意:给你n*n的矩阵和几种操作,问重复几次后会得到原图思路:每个命令都是一个置换,操作序列就是置换的乘积,我们可以最终的处理出这个矩阵,一个结论:对于一个长度为l的循环A,当且仅当m是l的整数倍的时候A^m才是全等置换,所以答案是多个循环的最小公倍数#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1100; int n, g[maxn][maxn], vis[maxn][maxn], save[maxn][maxn]; char str[maxn], tmp[maxn]; int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } int lcm(int a, int b) { return a / gcd(a, b) * b; } void id() { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) g[i][j] = save[i][j]; } void rot(int flag) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (flag) save[i][j] = g[n-j-1][i]; else save[n-j-1][i] = g[i][j]; } id(); } void sym(int flag) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) save[i][j] = g[i][n-1-j]; id(); } void bhsym(int flag) { for (int i = 0; i < n/2; i++) for (int j = 0; j < n; j++) save[i][j] = g[i][j]; for (int i = n/2; i < n; i++) for (int j = 0; j < n; j++) save[i][j] = g[i][n-1-j]; id(); } void bvsym(int flag) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (i < n / 2) save[i][j] = g[i][j]; else save[i][j] = g[3 * n / 2 - 1 - i][j]; } id(); } void div(int flag) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (flag == 1) { if (i & 1) save[i / 2 + n / 2][j] = g[i][j]; else save[i / 2][j] = g[i][j]; } else { if (i & 1) save[i][j] = g[i / 2 + n / 2][j]; else save[i][j] = g[i / 2][j]; } } id(); } void mix(int flag) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if ((i & 1) == 0) { if (flag) { if ((j & 1) == 0) save[i][j] = g[i][j / 2]; else save[i][j] = g[i + 1][j / 2]; } else { if ((j & 1) == 0) save[i][j / 2] = g[i][j]; else save[i + 1][j / 2] = g[i][j]; } } else { if (flag) { if ((j & 1) == 0) save[i][j] = g[i - 1][n / 2 + j / 2]; else save[i][j] = g[i][n / 2 + j / 2]; } else { if ((j & 1) == 0) save[i - 1][n / 2 + j / 2] = g[i][j]; else save[i][n / 2 + j / 2] = g[i][j]; } } } id(); } void change(char *str) { int len = strlen(str); int flag = 1; if (str[0] == '-') { flag = 0; str++; } if (strcmp(str, "tor") == 0) rot(flag); else if (strcmp(str, "mys") == 0) sym(flag); else if (strcmp(str, "myshb") == 0) bhsym(flag); else if (strcmp(str, "mysvb") == 0) bvsym(flag); else if (strcmp(str, "vid") == 0) div(flag); else if (strcmp(str, "xim") == 0) mix(flag); } void tra() { int len = strlen(str); int sn = 0; for (int i = len - 1; i >= 0; i--) { if (str[i] == ' ') { tmp[sn] = '\0'; change(tmp); sn = 0; } else { tmp[sn++] = str[i]; } } tmp[sn] = '\0'; change(tmp); } int solve() { int ans = 1; memset(vis, 0, sizeof(vis)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!vis[i][j]) { vis[i][j] = 1; int cnt = 1; int x = g[i][j] / n; int y = g[i][j] % n; while (!vis[x][y]) { cnt++; vis[x][y] = 1; int t = g[x][y] / n; y = g[x][y] % n; x = t; } ans = lcm(ans, cnt); } } } return ans; } void init() { scanf("%d", &n); getchar(); gets(str); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { g[i][j] = i * n + j; } } } int main() { int t; scanf("%d", &t); while (t--) { init(); tra(); printf("%d\n", solve()); if (t) printf("\n"); } return 0; }
UVA - 1156 Pixel Shuffle (置换+模拟)