1 条题解

  • 0
    @ 2026-5-3 22:48:31
    #include <algorithm>
    #include <cassert>
    #include <cmath>
    #include <iostream>
    #include <string>
    #include <tuple>
    #include <vector>
    using namespace std;
    
    // Returned values (x,y,g) satisfy x*a+y*b = g.
    // |x|+|y| is minimized, breaking ties with |x| <= |y|.
    // If g>0, all other solutions are of the form (x+n*(b/g))*a + (y-n*(a/g))*b = g.
    template<typename T> constexpr tuple<T,T,T> ExtendedGcd(T a, T b) {
    	if( b == 0 ) {
        if (a == 0) return {0, 0, 0};
        if (a < 0) return {-1, 0, -a};
        return {1, 0, a};
    	}
      T x, y, g;
      tie(x, y, g) = ExtendedGcd(b, a%b);
      return {y, x-y*(a/b), g};
    }
    
    struct Vec {
      int x, y, z;
      Vec operator-() const { return Vec{-x, -y, -z}; }
      Vec operator+(const Vec& v) const { return Vec{x+v.x, y+v.y, z+v.z}; }
      Vec &operator+=(const Vec& v) { x += v.x; y += v.y; z += v.z; return *this; }
      Vec &operator-=(const Vec& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
      Vec operator*(int c) const { return Vec{x*c, y*c, z*c}; }
      bool operator==(const Vec& v) const { return x == v.x && y == v.y && z == v.z; }
    };
    
    struct Leg {
      Vec s, f, d;
      int t;
      Leg operator-() const { return Leg{s+d*(t-1), f, -d, t}; }
      bool operator==(const Leg& l) const { return s == l.s && f == l.f && d == l.d && t == l.t; }
    };
    
    Vec readDir() {
      Vec ret{0, 0, 0};
      string s;
      cin >> s;
      (s[0] == 'x' ? ret.x : s[0] == 'y' ? ret.y : ret.z) = (s[1] == '+' ? 1 : -1);
      return ret;
    }
    
    void intersect(const Vec& a1, const Vec& a2, const Vec& b1, const Vec& b2, Vec* o1, Vec* o2) {
      o1->x = max(min(a1.x, a2.x), min(b1.x, b2.x));
      o1->y = max(min(a1.y, a2.y), min(b1.y, b2.y));
      o1->z = max(min(a1.z, a2.z), min(b1.z, b2.z));
      o2->x = min(max(a1.x, a2.x), max(b1.x, b2.x));
      o2->y = min(max(a1.y, a2.y), max(b1.y, b2.y));
      o2->z = min(max(a1.z, a2.z), max(b1.z, b2.z));
    }
    
    int main() {
      int N, K;
      while (cin >> N >> K) {
        vector<Vec> SA(N), SB(N);
        for (int i = 0; i < N; i++) {
          cin >> SA[i].x >> SA[i].y >> SA[i].z >> SB[i].x >> SB[i].y >> SB[i].z;
          SB[i] -= Vec{1, 1, 1};
        }
    
        vector<vector<Leg>> r(K);
        vector<int64_t> rc(K);
        for (int i = 0; i < K; i++) {
          Leg leg;
          cin >> leg.s.x >> leg.s.y >> leg.s.z;
          leg.f = readDir();
          leg.d = readDir();
    
          for (;;) {
            leg.t = 0;
            bool change;
            do {
              change = false;
              for (int j = 0; j < N; j++) {
                Vec v = leg.s + leg.d*leg.t;
                if (v.x >= SA[j].x && v.y >= SA[j].y && v.z >= SA[j].z &&
                    v.x <= SB[j].x && v.y <= SB[j].y && v.z <= SB[j].z) {
                  Vec a, b;
                  intersect(v, v + leg.d*1e9, SA[j], SB[j], &a, &b);
                  leg.t += (b.x-a.x)+(b.y-a.y)+(b.z-a.z)+1;
                  change = true;
                }
              }
            } while(change);
            bool collide = false;
            for (int j = 0; j < N; j++) {
              Vec v = leg.s + leg.f, a, b;
              intersect(v, v + leg.d*leg.t, SA[j], SB[j], &a, &b);
              if (b.x >= a.x && b.y >= a.y && b.z >= a.z) {
                leg.t = min(abs(v.x-a.x)+abs(v.y-a.y)+abs(v.z-a.z), abs(v.x-b.x)+abs(v.y-b.y)+abs(v.z-b.z));
                collide = true;
              }
            }
            assert(leg.t > 0);
    
            if (r[i].size() >= 2 && leg == r[i][1]) break;
            if (r[i].size()) rc[i] += leg.t;
    //cout << "r" << i << " leg" << r[i].size() << ": ";
    //cout << leg.s.x << ',' << leg.s.y << ',' << leg.s.z << ' ' << leg.t << ' ';
    //cout << leg.f.x << ',' << leg.f.y << ',' << leg.f.z << ' ';
    //cout << leg.d.x << ',' << leg.d.y << ',' << leg.d.z << endl;
            r[i].push_back(leg);
    
            if (collide) {
              leg.s = leg.s + leg.f + leg.d*leg.t;
              swap(leg.f, leg.d);
              leg.f = -leg.f;
            } else {
              leg.s = leg.s + leg.d*(leg.t-1);
              swap(leg.f, leg.d);
              leg.d = -leg.d;
            }
          }
    //cout << "rc" << i << ": " << rc[i] << endl;
        }
    
        int64_t ret = 1e18;
        for (int i = 0; i < K; i++)
        for (int j = i+1; j < K; j++) {
          if (r[i][0].s == r[j][0].s && r[i][0].f == r[j][0].f) ret = 0;
    
          bool opp = false;
          for (int ji = 1, jt = r[j][0].t; ji < r[j].size(); jt += r[j][ji].t, ji++) if (r[j][ji] == -r[i][1]) {
            ret = min(ret, int64_t((jt+r[i][1].t+r[i][0].t-1)/2) % (rc[i]/2));
            opp = true;
          }
          if (opp) continue;
    
          for (int ii = 1, it = r[i][0].t; ii < r[i].size(); it += r[i][ii].t, ii++)
          for (int ji = 1, jt = r[j][0].t; ji < r[j].size(); jt += r[j][ji].t, ji++) if (r[i][ii].f == r[j][ji].f) {
            Vec a, b;
            intersect(r[i][ii].s, r[i][ii].s+r[i][ii].d*(r[i][ii].t-1),
                      r[j][ji].s, r[j][ji].s+r[j][ji].d*(r[j][ji].t-1), &a, &b);
            if (a == b) {
              int64_t t1 = it + abs(r[i][ii].s.x-a.x) + abs(r[i][ii].s.y-a.y) + abs(r[i][ii].s.z-a.z);
              int64_t t2 = jt + abs(r[j][ji].s.x-a.x) + abs(r[j][ji].s.y-a.y) + abs(r[j][ji].s.z-a.z);
              int64_t x, y, g;
              tie(x, y, g) = ExtendedGcd(rc[i], rc[j]);
              if (t1%g == t2%g) {
                int64_t c = rc[i]*rc[j]/g, t = (t1*y)%rc[i]*rc[j]/g + (t2*x)%rc[j]*rc[i]/g;
                ret = min(ret, (t%c+c)%c);
              }
            }
          }
        }
    
        if (ret == 1e18) cout << "ok" << endl; else cout << ret << endl;
      }
    }
    
    • 1

    「ICPC World Finals 2020」太空墙壁

    信息

    ID
    8532
    时间
    15000ms
    内存
    2048MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者