zoukankan      html  css  js  c++  java
  • UVa 12171 题解

    英文题面不怎么友好,大家还是自行通过紫书了解题面吧。。。

    解题思路:

      1. 面对500 ^ 3的数据范围,我们需要先用离散化解决掉爆空间的问题。

      2. 由于我们要求的总体积包括内空部分的体积,我们可以用flood_fill来解决。

    注意事项:(几个细节问题)

      1. unique函数的正确使用姿势:如果是从一开始存数,注意最后要多减去1.

      2. 染色时每个三维坐标上的点代表一个长方形,所以右端点不能染色。

        3. 可以用结构体封装一下各个操作。

    AC代码:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <cstdio>
    #include <cstdlib>
    
    using namespace std;
    
    const int dx[] = {1, -1,  0,  0,  0,  0};
    const int dy[] = {0,  0,  1, -1,  0,  0};
    const int dz[] = {0,  0,  0,  0,  1, -1};
    
    int T, n, v, s;
    int x1[507], y1[507], z1[507], x0[507], y0[507], z0[507];
    
    int nx = 0, ny = 0, nz= 0;
    int lx[110], ly[110], lz[110];
    int color[104][104][104];
    
    struct cell{
        int x, y, z;
    
        cell(int x = 0, int y = 0, int z = 0): x(x), y(y), z(z) {}
    
        void setvis() const { color[x][y][z] = 2; }
    
        bool getvis() const { return color[x][y][z] == 2; }
    
        bool issolid() const { return color[x][y][z] == 1; }
    
        bool invalid() const {
            if (x <= 0 || y <= 0 || z <= 0 || x >= nx || y >= ny || z >= nz ) return true;
            return false;
        }
    
        int area(int dir) const {
            if (dx[dir] != 0) return (ly[y + 1] - ly[y]) * (lz[z + 1] - lz[z]);
            else if (dy[dir] != 0) return (lx[x + 1] - lx[x]) * (lz[z + 1] - lz[z]);
            return (lx[x + 1] - lx[x]) * (ly[y + 1] - ly[y]);
        }
    
        int volume() const { return (lx[x + 1] - lx[x]) * (ly[y + 1] - ly[y]) * (lz[z + 1] - lz[z]); }
    
    };
    
    int read()
    {
        int x = 0;
        int k = 1;
        char c = getchar();
    
        while (c > '9' || c < '0')
            if (c == '-') k = -1, c = getchar();
            else c = getchar();
        while (c >= '0' && c <= '9')
            x = x * 10 + c - '0',
            c = getchar();
    
        return k * x;
    }
    
    void  discretization(int* x, int& l)
    {
        sort(x + 1, x + l + 1);
        l = unique(x + 1, x + l + 1) - x - 1;
    }
    
    int get_ID(int *x, int l, int k)
    {
        return lower_bound(x + 1, x + l + 1, k) - x;
    }
    
    void flood_fill()
    {
        cell c(1, 1, 1);
        c.setvis();
        queue<cell> q;
        q.push(c);
        while (!q.empty())
        {
            cell c = q.front();
            q.pop();
            v += c.volume();
            for (int i = 0; i < 6; ++i)
            {
                cell c2(c.x + dx[i], c.y + dy[i], c.z + dz[i]);
                if (c2.invalid()) continue;
                if (c2.issolid()) s += c2.area(i);
                else if (!c2.getvis())
                {
                    c2.setvis();
                    q.push(c2);
                }
            }
        }
        v = 1001 * 1001 * 1001 - v;
    }
    
    int main()
    {
        T = read();
        while (T--)
        {
            v = 0, s = 0;
            memset(color, 0, sizeof(color));
            n = read();
            lx[2] = ly[2] = lz[2] = 0;
            lx[1] = ly[1] = lz[1] = 1001;
            nx = ny = nz = 2;
            for (int i = 1; i <= n; ++i)
                x0[i] = read(),
                y0[i] = read(),
                z0[i] = read(),
                x1[i] = read(),
                y1[i] = read(),
                z1[i] = read(),
                lx[++nx] = x0[i],
                lx[++nx] = x0[i] + x1[i],
                ly[++ny] = y0[i],
                ly[++ny] = y0[i] + y1[i],
                lz[++nz] = z0[i],
                lz[++nz] = z0[i] + z1[i];
    
    
            discretization(lx, nx);
            discretization(ly, ny);
            discretization(lz, nz);
    
            for (int t = 1; t <= n; ++t)
            {
                int sx = get_ID(lx, nx, x0[t]);
                int ex = get_ID(lx, nx, x0[t] + x1[t]);
                int sy = get_ID(ly, ny, y0[t]);
                int ey = get_ID(ly, ny, y0[t] + y1[t]);
                int sz = get_ID(lz, nz, z0[t]);
                int ez = get_ID(lz, nz, z0[t] + z1[t]);
                for (int i = sx; i < ex; ++i)
                    for (int j = sy; j < ey; ++j)
                        for (int l = sz; l < ez; ++l)
                            color[i][j][l] = 1;
            }
    
            flood_fill();
    
            printf("%d %d
    ", s, v);
        }
    }
  • 相关阅读:
    CSS hack
    字符串中常用的方法
    排序算法
    拾遗
    数组类型检测
    数组常用的方法
    go 文件服务器(标准库) 添加关机,睡眠,退出功能
    go cmd 交互 初始化执行某些命令
    go 内网IP及外网IP获取
    go 快排实现
  • 原文地址:https://www.cnblogs.com/yanyiming10243247/p/9667984.html
Copyright © 2011-2022 走看看