uva 1156 - Pixel Shuffle(模拟+置换)

来源:互联网 发布:mac黑苹果安装教程 编辑:程序博客网 时间:2024/06/10 03:09

题目链接:uva 1156 - Pixel Shuffle

题目大意:给定一个N*N的黑白位图,有7种操作,并且对应在指令后加上‘-’即为操作的逆,给定N和一系列操作,(从最后一个开始执行),问说这一套指令需要执行多少次才能形成循环。

解题思路:模拟指令执行后获得一个置换,分解成若干的循环,各个循环长度的最小公倍数即使答案。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = (1<<10) + 5;int N, s[maxn][maxn], f[maxn][maxn];int c, v[maxn];const char sign[maxn][10] = {"id", "id-", "rot", "rot-", "sym", "sym-", "bhsym", "bhsym-", "bvsym",    "bvsym-", "div", "div-", "mix", "mix-" };inline int get_sign (char* word) {    for (int i = 0; i < 14; i++)        if (strcmp(word, sign[i]) == 0)            return i;    return -1;}// 逆时针90void rot (bool flag) {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (flag)                f[i][j] = s[N-1-j][i];            else                f[N-1-j][i] = s[i][j];        }    }    memcpy(s, f, sizeof(f));}// 水平翻转void sym () {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++)            f[i][j] = s[i][N-1-j];    }    memcpy(s, f, sizeof(f));}// 下一半水平翻转void bhsym () {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (i >= N/2)                f[i][j] = s[i][N-1-j];            else                f[i][j] = s[i][j];        }    }    memcpy(s, f, sizeof(f));}// 下一半垂直翻转void bvsym () {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (i >= N/2)                f[i][j] = s[3 * N / 2 - i - 1][j];            else                f[i][j] = s[i][j];        }    }    memcpy(s, f, sizeof(f));}// 分成两份void div (bool flag) {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (flag) {                if (i&1)                    f[i/2 + N/2][j] = s[i][j];                else                    f[i/2][j] = s[i][j];            } else {                if (i&1)                    f[i][j] = s[i/2 + N/2][j];                else                    f[i][j] = s[i/2][j];            }        }    }    memcpy(s, f, sizeof(f));}void mix (bool flag) {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (i&1) {                if (flag) {                    if (j&1)                        f[i][j] = s[i][N/2 + j/2];                    else                        f[i][j] = s[i-1][N/2 + j/2];                } else {                    if (j&1)                        f[i][N/2+j/2] = s[i][j];                    else                        f[i-1][N/2+j/2] = s[i][j];                }            } else {                if (flag) {                    if (j&1)                        f[i][j] = s[i+1][j/2];                    else                        f[i][j] = s[i][j/2];                } else {                    if (j&1)                        f[i+1][j/2] = s[i][j];                    else                        f[i][j/2] = s[i][j];                }            }        }    }    /*    if (N&1) {        for (int i = 0; i < N; i++) {            f[i][n] = s[i][n];            f[n][i] = s[n][i];        }    }    */    memcpy(s, f, sizeof(f));}void put () {    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++)            printf("%d ", s[i][j]);        printf("\n");    }}void handle () {    for (int i = c-1; i >= 0; i--) {        switch (v[i]) {            case 0:            case 1:                break;            case 2:                rot(true);                break;            case 3:                rot(false);                break;            case 4:            case 5:                sym();                break;;            case 6:            case 7:                bhsym();                break;            case 8:            case 9:                bvsym();                break;            case 10:                div(true);                break;            case 11:                div(false);                break;            case 12:                mix(true);                break;            case 13:                mix(false);                break;        }    }}ll gcd (ll a, ll b) {    return b == 0 ? a : gcd(b, a % b);}ll lcm (ll a, ll b) {    return a / gcd (a, b) * b;}ll solve () {    char str[maxn], word[maxn];    gets(str);    int len = strlen(str), mv = 0;    c = 0;    for (int i = 0; i <= len; i++) {        if ((str[i] >= 'a' && str[i] <= 'z') || str[i] == '-')            word[mv++] = str[i];        else {            word[mv] = '\0';            v[c++] = get_sign(word);            mv = 0;        }    }    handle();    ll ret = 1;    memset(f, 0, sizeof(f));    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (f[i][j])                continue;            int x = s[i][j] / N;            int y = s[i][j] % N;            ll cnt = 0;            while (f[x][y] == 0) {                f[x][y] = 1;                cnt++;                int tmp = s[x][y];                x = tmp / N;                y = tmp % N;            }            ret = lcm(ret, cnt);        }    }    return ret;}int main () {    int cas;    scanf("%d", &cas);    while (cas--) {        scanf("%d%*c", &N);        for (int i = 0; i < N; i++)            for (int j = 0; j < N; j++)                s[i][j] = i * N + j;        printf("%lld\n", solve());        if (cas)            printf("\n");    }    return 0;}
1 0
原创粉丝点击