UVa197 - Cube(TLE)

/* Time Limit exceeded 还有没有什么更好的方法*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 200
#define N 4
#define BUFLEN 30

typedef struct point3 {
    int x, y, z;
} point3;

typedef struct typea {
    point3 p[N];
    int n;

} typea;

int rot(typea ta, int type, int angle, typea *res);
int translate(typea ta, int type, typea *res);
point3 dotRotX(point3 pa, int angle, point3 pbase);
point3 dotRotY(point3 pa, int angle, point3 pbase);
point3 dotRotZ(point3 pa, int angle, point3 pbase);
point3 dotTranslateXPos(point3 pa);
point3 dotTranslateXNeg(point3 pa);
point3 dotTranslateYPos(point3 pa);
point3 dotTranslateYNeg(point3 pa);
point3 dotTranslateZPos(point3 pa);
point3 dotTranslateZNeg(point3 pa);
int is_ok(point3 pa);
int is_equal(typea ta, typea tb);
int is_dotEqual(point3 pa, point3 pb);
void dfs(typea t, int type);
void init();
void depthFistSearch(int cur);
int is_feasible(typea ta);
void set_flag(typea ta, int flag);
void clear_flag(typea ta);
void output();
int cmp_typea(const void *a, const void *b);

typea taArray[MAX], tAllArray[7][MAX];
int lenArray[7];
int len;
int vis[BUFLEN];
int solnum;

int main()
{
    int i;
    char buf[BUFLEN];
    int pos;
    char *p = NULL, *tmp = NULL;
    typea ta;

#ifndef ONLINE_JUDGE
    freopen("d:\\UVa\\uva_in.txt", "r", stdin);
    freopen("d:\\UVa\\uva_out.txt", "w", stdout);
#endif

    init();

    while (gets(buf) != NULL) {
        memset(vis, 0, sizeof(vis));
        tmp = buf;
        i = 0;
        ta.n = 4;
        while ((p = strchr(tmp, 'a')) != NULL) {
            pos = p - buf;
            tmp = p + 1;
            ta.p[i].x = pos % 3;
            ta.p[i].y = pos % 9 / 3;
            ta.p[i].z = pos / 9;
            i++;
        }

        taArray[0] = ta;
        len = 1;
        dfs(ta, 0);
        memcpy(tAllArray[0], taArray, sizeof(struct typea) * len);
        lenArray[0] = len;

        depthFistSearch(0);
        printf("\n");
    }

    return 0;
}

int rot(typea ta, int type, int angle, typea *res)
{
    int i, n = ta.n;

    res->n = n;

    if (type == 0) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotRotX(ta.p[i], angle, ta.p[1]);
        }
    } else if (type == 1) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotRotY(ta.p[i], angle, ta.p[1]);
        }
    } else if (type == 2) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotRotZ(ta.p[i], angle, ta.p[1]);
        }
    }

    for (i = 0; i < n; i++) {
        if (!is_ok(res->p[i]))
            return 0;
    }

    return 1;
}

point3 dotRotX(point3 pa, int angle, point3 pbase)
{
    point3 tmp = pbase;
    int coffia, coffib;

    pa.x -= pbase.x;
    pa.y -= pbase.y;
    pa.z -= pbase.z;

    if (angle == 90) {
        coffia = 0;
        coffib = 1;
    } else if (angle == 180) {
        coffia = -1;
        coffib = 0;
    } else if (angle == 270) {
        coffia = 0;
        coffib = -1;
    }

    tmp.x = pa.x;
    tmp.y = pa.y * coffia - pa.z * coffib;
    tmp.z = pa.y * coffib + pa.z * coffia;

    return tmp;
}

point3 dotRotY(point3 pa, int angle, point3 pbase)
{
    point3 tmp = pbase;
    int coffia, coffib;

    pa.x -= pbase.x;
    pa.y -= pbase.y;
    pa.x -= pbase.z;

    if (angle == 90) {
        coffia = 0;
        coffib = 1;
    } else if (angle == 180) {
        coffia = -1;
        coffib = 0;
    } else if (angle == 270) {
        coffia = 0;
        coffib = -1;
    }

    tmp.x += pa.x * coffia + pa.z * coffib;
    tmp.y += pa.y;
    tmp.z += -pa.x * coffib + pa.z * coffia;

    return tmp;
}

point3 dotRotZ(point3 pa, int angle, point3 pbase)
{
    point3 tmp = pbase;
    int coffia, coffib;

    pa.x -= pbase.x;
    pa.y -= pbase.y;
    pa.z -= pbase.z;

    if (angle == 90) {
        coffia = 0;
        coffib = 1;
    } else if (angle == 180) {
        coffia = -1;
        coffib = 0;
    } else if (angle == 270) {
        coffia = 0;
        coffib = -1;
    }

    tmp.x += pa.x * coffia - pa.y * coffib;
    tmp.y += pa.x * coffib + pa.y * coffia;
    tmp.z += pa.z;

    return tmp;
}

int is_ok(point3 pa)
{

    if (pa.x < 0 || pa.x > 2 || pa.y < 0 || pa.y > 2 || pa.z < 0 || pa.z > 2)
        return 0;

    return 1;
}

point3 dotTranslateXPos(point3 pa)
{
    point3 tmp;

    tmp.x = pa.x + 1;
    tmp.y = pa.y;
    tmp.z = pa.z;

    return tmp;
}

point3 dotTranslateXNeg(point3 pa)
{
    point3 tmp;

    tmp.x = pa.x - 1;
    tmp.y = pa.y;
    tmp.z = pa.z;

    return tmp;
}

point3 dotTranslateYPos(point3 pa)
{
    point3 tmp;

    tmp.x = pa.x;
    tmp.y = pa.y + 1;
    tmp.z = pa.z;

    return tmp;
}

point3 dotTranslateYNeg(point3 pa)
{
    point3 tmp;

    tmp.x = pa.x;
    tmp.y = pa.y - 1;
    tmp.z = pa.z;

    return tmp;
}

point3 dotTranslateZPos(point3 pa)
{
    point3 tmp;

    tmp.x = pa.x;
    tmp.y = pa.y;
    tmp.z = pa.z + 1;

    return tmp;
}

point3 dotTranslateZNeg(point3 pa)
{
    point3 tmp;

    tmp.x = pa.x;
    tmp.y = pa.y;
    tmp.z = pa.z - 1;

    return tmp;
}

int translate(typea ta, int type, typea *res)
{
    int i, n;
    n = ta.n;

    res->n = n;

    if (type == 0) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotTranslateXPos(ta.p[i]);
        }
    } else if (type == 1) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotTranslateXNeg(ta.p[i]);
        }
    } else if (type == 2) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotTranslateYPos(ta.p[i]);
        }
    } else if (type == 3) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotTranslateYNeg(ta.p[i]);
        }
    } else if (type == 4) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotTranslateZPos(ta.p[i]);
        }
    } else if (type == 5) {
        for (i = 0; i < n; i++) {
            res->p[i] = dotTranslateZNeg(ta.p[i]);
        }
    }

    for (i = 0; i < n; i++) {
        if (!is_ok(res->p[i]))
            return 0;
    }

    return 1;
}

void dfs(typea t, int type)
{
    int i, j, k;
    int flag, ok;
    typea tmp;

    if (type) {
        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                flag = rot(t, i, j * 90 + 90, &tmp);
                if (flag) {
                    ok = 1;
                    for (k = 0; k < len; k++) {
                        if (is_equal(tmp, taArray[k])) {
                            ok = 0;
                            break;
                        }
                    }
                    if (ok) {
                        taArray[len++] = tmp;
                        dfs(tmp, type);

                    }

                }
            }
        }
    }



    for (i = 0; i < 6; i++) {
        flag = translate(t, i, &tmp);
        if (flag) {
            ok = 1;
            for (k = 0; k < len; k++) {
                if (is_equal(tmp, taArray[k])) {
                    ok = 0;
                    break;
                }
            }
            if (ok) {
                taArray[len++] = tmp;
                dfs(tmp, type);

            }

        }
    }
}

int is_equal(typea ta, typea tb)
{
    int i, n;
    n = ta.n;

    qsort(ta.p, n, sizeof(struct point3), cmp_typea);
    qsort(tb.p, n, sizeof(struct point3), cmp_typea);
    for (i = 0; i < n; i++) {
        if (!is_dotEqual(ta.p[i], tb.p[i]))
            return 0;
    }

    return 1;
}

int is_dotEqual(point3 pa, point3 pb)
{
    if (pa.x != pb.x)
        return 0;
    if (pa.y != pb.y)
        return 0;
    if (pa.z != pb.z)
        return 0;

    return 1;
}

void init()
{
    int i;
    typea ta;

    ta.n = 3;
    ta.p[0].x = 1, ta.p[0].y = 0, ta.p[0].z = 0;
    ta.p[1].x = 0, ta.p[1].y = 0, ta.p[1].z = 0;
    ta.p[2].x = 0, ta.p[2].y = 1, ta.p[2].z = 0;
    taArray[0] = ta;
    len = 1;
    dfs(ta, 1);
    memcpy(tAllArray[1], taArray, sizeof(struct typea) * len);
    lenArray[1] = len;

    ta.n = 4;
    ta.p[0].x = 0, ta.p[0].y = 0, ta.p[0].z = 0;
    ta.p[1].x = 0, ta.p[1].y = 1, ta.p[1].z = 0;
    ta.p[2].x = 1, ta.p[2].y = 1, ta.p[2].z = 0;
    ta.p[3].x = 0, ta.p[3].y = 2, ta.p[3].z = 0;
    taArray[0] = ta;
    len = 1;
    dfs(ta, 1);
    memcpy(tAllArray[2], taArray, sizeof(struct typea) * len);
    lenArray[2] = len;

    ta.n = 4;
    ta.p[0].x = 2, ta.p[0].y = 0, ta.p[0].z = 0;
    ta.p[1].x = 1, ta.p[1].y = 0, ta.p[1].z = 0;
    ta.p[2].x = 1, ta.p[2].y = 1, ta.p[2].z = 0;
    ta.p[3].x = 0, ta.p[3].y = 1, ta.p[3].z = 0;
    taArray[0] = ta;
    len = 1;
    dfs(ta, 1);
    memcpy(tAllArray[3], taArray, sizeof(struct typea) * len);
    lenArray[3] = len;

    ta.n = 4;
    ta.p[0].x = 1, ta.p[0].y = 0, ta.p[0].z = 0;
    ta.p[1].x = 0, ta.p[1].y = 0, ta.p[1].z = 0;
    ta.p[2].x = 0, ta.p[2].y = 1, ta.p[2].z = 0;
    ta.p[3].x = 0, ta.p[3].y = 0, ta.p[3].z = 1;
    taArray[0] = ta;
    len = 1;
    dfs(ta, 1);
    memcpy(tAllArray[4], taArray, sizeof(struct typea) * len);
    lenArray[4] = len;

    ta.n = 4;
    ta.p[0].x = 0, ta.p[0].y = 0, ta.p[0].z = 0;
    ta.p[1].x = 0, ta.p[1].y = 1, ta.p[1].z = 0;
    ta.p[2].x = 1, ta.p[2].y = 1, ta.p[2].z = 0;
    ta.p[3].x = 1, ta.p[3].y = 1, ta.p[3].z = 1;
    taArray[0] = ta;
    len = 1;
    dfs(ta, 1);
    memcpy(tAllArray[5], taArray, sizeof(struct typea) * len);
    lenArray[5] = len;

    ta.n = 4;
    ta.p[0].x = 0, ta.p[0].y = 0, ta.p[0].z = 0;
    ta.p[1].x = 0, ta.p[1].y = 1, ta.p[1].z = 0;
    ta.p[2].x = 0, ta.p[2].y = 1, ta.p[2].z = 1;
    ta.p[3].x = 1, ta.p[3].y = 1, ta.p[3].z = 1;
    taArray[0] = ta;
    len = 1;
    dfs(ta, 1);
    memcpy(tAllArray[6], taArray, sizeof(struct typea) * len);
    lenArray[6] = len;
}

int is_feasible(typea ta)
{
    int n = ta.n, i;
    int x, y, z;
    int sum;

    for (i = 0; i < n; i++) {
        x = ta.p[i].x;
        y = ta.p[i].y;
        z = ta.p[i].z ;

        sum = z * 9 + y * 3 + x;
        if (vis[sum])
            return 0;
    }

    return 1;
}

void set_flag(typea ta, int flag)
{
    int n = ta.n, i;
    int x, y, z;
    int sum;

    for (i = 0; i < n; i++) {
        x = ta.p[i].x;
        y = ta.p[i].y;
        z = ta.p[i].z ;

        sum = z * 9 + y * 3 + x;
        vis[sum] = flag + 1;
    }
}

void clear_flag(typea ta)
{
    int n = ta.n, i;
    int x, y, z;
    int sum;

    for (i = 0; i < n; i++) {
        x = ta.p[i].x;
        y = ta.p[i].y;
        z = ta.p[i].z ;

        sum = z * 9 + y * 3 + x;
        vis[sum] = 0;
    }
}

void output()
{
    int i;

    for (i = 0; i < 27; i++)
        printf("%c", vis[i] - 1 + 'a');

    printf("\n");
}

void depthFistSearch(int cur)
{
    int i, length;

    if (cur >= 7) {
        output();
        return;
    }

    length = lenArray[cur];
    for (i = 0; i < length; i++) {
        if (is_feasible(tAllArray[cur][i])) {
            set_flag(tAllArray[cur][i], cur);
            depthFistSearch(cur + 1);
            clear_flag(tAllArray[cur][i]);
        }
    }
}

int cmp_typea(const void *a, const void *b)
{
    point3 *pa = a, *pb = b;
    if (pa->x != pb->x)
        return pa->x - pb->x;
    if (pa->y != pb->y)
        return pa->y - pb->y;
    return pa->z - pb->z;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值