Language: C++

#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;


struct Solver{
    int n;
    static const int dx[6] = { 0,  1, 1, 0, -1, -1};
    static const int dy[6] = {-1, -1, 0, 1,  1,  0};
    int get_r(int fx, int fy, int tx, int ty){
        // return r such that fx + dx[r] == tx and fy + dy[r] == ty
        int ddx = tx - fx;
        int ddy = ty - fy;
        for(int r = 0; r < 6; r++){
            if(dx[r] == ddx && dy[r] == ddy) {
                return r;
            }
        }
        return -1;
    }

    typedef tuple<int, int, vector<int>> state;
    set< vector<int> > validset;
    map< vector<int>, vector<state> > nextstate;

    void make_validset(){
        for(int s = 0; s < (1 << (3 * (n - 1))); s++){
            vector<int> x, y;

            vector<int> rv(n - 1);
            REP(i, n - 1) rv[i] = (s >> (3 * i) & 7);

            // rは6以下
            REP(i, n - 1) if(rv[i] >= 6) goto fail;

            // 各頂点の座標を計算する
            x.push_back(0); y.push_back(0);
            REP(i, n - 1) x.push_back(x.back() + dx[ rv[i] ]);
            REP(i, n - 1) y.push_back(y.back() + dy[ rv[i] ]);

            // 本来隣り合っている以外の節が隣の窪みに来たらしぬ
            REP(i, n) REP(j, n) if(abs(i - j) >= 2 && get_r(x[i], y[i], x[j], y[j]) != -1) goto fail;
            
            // 同じくぼみには入らない
            REP(i, n) REP(j, n) if(abs(i - j) >= 1 && x[i] == x[j] && y[i] == y[j]) goto fail;

            // 大丈夫
            validset.insert(rv);

            fail:;
        }
    }

    void make_nextstate(){
        for(const vector<int>& rv : validset){
            // print(rv);
            vector<int> x, y;
            x.push_back(0); y.push_back(0);
            REP(i, n - 1) x.push_back(x.back() + dx[ rv[i] ]);
            REP(i, n - 1) y.push_back(y.back() + dy[ rv[i] ]);

            function<void(int)> rec = [&](int k){
                if(k >= n){
                    vector<int> nrv;
                    REP(i, n - 1) nrv.push_back(get_r(x[i], y[i], x[i + 1], y[i + 1]));

                    if(validset.count(nrv)) {
                        nextstate[rv].push_back(make_tuple(x[0], y[0], nrv));
                    }
                }else{
                    if(k - 1 < 0 || get_r(x[k - 1], y[k - 1], x[k], y[k]) >= 0){
                        rec(k + 1);
                    }
                    for(int r = 0; r < 6; r++){
                        x[k] += dx[r];
                        y[k] += dy[r];
                        if((k - 1 < 0 || get_r(x[k - 1], y[k - 1], x[k], y[k]) >= 0) && 
                           (k + 1 >= n || get_r(x[k], y[k], x[k + 1], y[k + 1]) >= 0) ){
                            rec(k + 2);
                        }
                        x[k] -= dx[r];
                        y[k] -= dy[r];
                    }
                }
            };
            rec(0);
            assert(x[0] == 0 && y[0] == 0);
        }
    }

    Solver(int n_) : n(n_) {
        make_validset();
        make_nextstate();
    }

    int init_x[8], init_y[8];
    int goal_x, goal_y;
    set< pair<int, int> > rock;
    void input(){
        REP(i, n) cin >> init_x[i] >> init_y[i];

        int k;
        cin >> k;
        while(k--){
            int x, y;
            cin >> x >> y;
            rock.insert(make_pair(x, y));
        }

        cin >> goal_x >> goal_y;
    }
    void print(const vector<int>& v){
        printf("{");
        REP(i, v.size()){
            printf("%d", v[i]);
            if(i + 1 == v.size()) cout << "}" << endl;
            else cout << ", ";
        }
    }
    void print(state s){
        printf("n = %d bx = %d by = %d rv = ", n, get<0>(s), get<1>(s));
        print(get<2>(s));
        vector<int> x, y;
        x.push_back(get<0>(s));
        y.push_back(get<1>(s));
        REP(i, n - 1) x.push_back(x.back() + dx[ get<2>(s)[i] ]);
        REP(i, n - 1) y.push_back(y.back() + dy[ get<2>(s)[i] ]);
        printf("x = "); print(x);
        printf("y = "); print(y);
    }

    int solve(){
        vector<int> init_rv;
        REP(i, n - 1) {
            init_rv.push_back(get_r(init_x[i], init_y[i], init_x[i + 1], init_y[i + 1]));
        }
        assert(validset.count(init_rv));
        assert(nextstate.count(init_rv));
        state init(init_x[0], init_y[0], init_rv);
        map<state, int> cost;
        queue<state> que;
        cost[init] = 0;
        que.push(init);
        while(!que.empty()){
            state s = que.front(); que.pop();
            int c = cost[s];
            int bx = get<0>(s);
            int by = get<1>(s);
            vector<int> rv = get<2>(s);
            assert(rv.size() == n - 1);

            bool ng = false;
            if(rock.count(make_pair(bx, by))) ng = true;
            for(int i = 0, x = bx, y = by; i < n - 1; i++){
                x += dx[ rv[i] ];
                y += dy[ rv[i] ];
                if(rock.count(make_pair(x, y))) ng = true;
            }
            if(ng) continue;

            // print(s);

            if(bx == goal_x && by == goal_y){
                return c;
            }

            if(max(abs(bx - goal_x), abs(by - goal_y)) + c >= 21) continue;

            for(state ns : nextstate[rv]){
                state nexts(bx + get<0>(ns), by + get<1>(ns), get<2>(ns));
                if(cost.count(nexts)) continue;
                cost[nexts] = c + 1;
                que.push(nexts);
            }
        }
        return -1;
    }
};

int main(){
    int n;
    while(cin >> n && n > 0){
        Solver solver(n);
        solver.input();
        cout << solver.solve() << endl;
    }
    return 0;
}

Compiler output:
a.cc:9:22: error: 'constexpr' needed for in-class initialization of static data member 'const int Solver::dx [6]' of non-integral type [-fpermissive]
    9 |     static const int dx[6] = { 0,  1, 1, 0, -1, -1};
      |                      ^~
a.cc:10:22: error: 'constexpr' needed for in-class initialization of static data member 'const int Solver::dy [6]' of non-integral type [-fpermissive]
   10 |     static const int dy[6] = {-1, -1, 0, 1,  1,  0};
      |                      ^~