ZOJ 3429 Cube Simulation (思维题)

本文介绍了一种在无限大的三维空间中进行坐标变换和查询的算法。通过使用填充、平面交换等操作,实现坐标系内特定点的标号确定及查询。采用三个数组分别记录X、Y、Z轴的坐标值,并利用这些数组来处理平面交换操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3429

题意

给一个无限大的长方体,有击中操作:

  • FILL(X,Y,Z) : 按照先Z轴,后Y轴,再X轴标号,
  • SWAP1(x1,x2): 交换由X轴坐标为x1的点构成的平面 和 由X轴坐标为x2的点构成的平面
  • SWAP2(y1,y2): 交换由Y轴坐标为y1的点构成的平面 和 由Y轴坐标为y2的点构成的平面
  • SWAP3(z1,z2): 交换由Z轴坐标为z1的点构成的平面 和 由Z轴坐标为z2的点构成的平面
  • FIND(value) : 输出找标号为value的点的坐标
  • QUERY(x,y,z): 输出点(x, y, z)处的标号

解法

可以看出交换操作并不影响另外的两个坐标,比如SWAP1(x1, x2), 并不影响y1, y2, z1, z2。
所以可以用三个数组x, y, z表示坐标,交换时只需交换相应的数组内的值
初始时各位置的标号可以很容易算出

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1100;
int main() {
    char op[10];
    int X, Y, Z;
    int a, b, c, val;
    int px, py, pz;
    int x[N], y[N], z[N];
    while(~scanf("%s", op)) {
        if(strcmp(op, "FILL") == 0) {
            scanf("%d%d%d", &X, &Y, &Z);
            printf("START\n");
            for(int i = 0; i < X; i++)
                x[i] = i;
            for(int i = 0; i < Y; i++)
                y[i] = i;
            for(int i = 0; i < Z; i++)
                z[i] = i;
        }
        else if(strcmp(op, "SWAP1") == 0) {
            scanf("%d%d", &a, &b);
            swap(x[a], x[b]);
        }
        else if(strcmp(op, "SWAP2") == 0) {
            scanf("%d%d", &a, &b);
            swap(y[a], y[b]);
        }
        else if(strcmp(op, "SWAP3") == 0) {
            scanf("%d%d", &a, &b);
            swap(z[a], z[b]);
        }
        else if(strcmp(op, "FIND") == 0) {
            scanf("%d", &val);
            if(val > X * Y * Z)
                continue;
            a = (val - 1) / (Z * Y);
            b = ((val - 1) % (Z * Y)) / Z;
            c = (val - 1) % Z;
            for(int i = 0; i < X; i++) {if(x[i] == a) {px = i; break; } }
            for(int i = 0; i < Y; i++) {if(y[i] == b) {py = i; break; } }
            for(int i = 0; i < Z; i++) {if(z[i] == c) {pz = i; break; } }
            printf("%d %d %d\n", px, py, pz);
        }
        else if(strcmp(op, "QUERY") == 0) {
            scanf("%d%d%d", &a, &b, &c);
            printf("%d\n", Y * Z * x[a] + Z * y[b] + z[c] + 1);
        }
    }
    return 0;
}

Source

ZOJ Monthly, November 2010

转载于:https://www.cnblogs.com/acm_record/p/4753667.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值