Loading

THUPC2022初赛

J. THUPC

先按照行列坐标排序,并合并相交的线段

之后只有 \(15\) 条线段,并且一个字符的拼接方式唯一,直接 dfs 即可

// input
17
1 0 5 2
0 0 3 5
0 3 4 5
1 2 7 7
1 2 7 10
0 7 10 4
0 11 13 1
1 1 7 11
1 1 7 13
1 0 6 15
0 15 16 5
0 15 16 6
1 5 6 16
1 3 6 18
1 4 7 18
0 18 21 3
0 18 21 7
// output
Yes
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

struct LineUp {
    int d, u, x;
    int id;
};
bool operator < (LineUp l1, LineUp l2) {
    return l1.x != l2.x ? l1.x < l2.x : 
           l1.d != l2.d ? l1.d < l2.d : 
                          l1.u > l2.u;
}

struct LineLeft {
    int l, r, y;
    int id;
};

bool operator < (LineLeft l1, LineLeft l2) {
    return l1.y != l2.y ? l1.y < l2.y : 
           l1.l != l2.l ? l1.l < l2.l : 
                          l1.r > l2.r;
}

vector<LineUp> lu;
vector<LineLeft> ll;
int cnt;

int n;

int fa[N];
int getfa(int x) {
    return x == fa[x] ? x : fa[x] = getfa(fa[x]);
}

char str[N] = "THUPC";
int vislu[N], visll[N];

#define make_LL(n) int l##n = L##n.l, r##n = L##n.r, y##n = L##n.y
#define make_LU(n) int d##n = L##n.d, u##n = L##n.u, x##n = L##n.x

int check_T(LineLeft L1, LineUp L2) {
    make_LL(1);
    make_LU(2);
    
    return getfa(L1.id) == getfa(L2.id)
    && d2 < y1 && y1 == u2 && l1 < x2 && x2 < r1;
}

int check_H(LineUp L3, LineLeft L4, LineUp L5) {
    make_LU(3);
    make_LL(4);
    make_LU(5);
    
    return getfa(L3.id) == getfa(L4.id) && getfa(L4.id) == getfa(L5.id)
    && d3 == d5 && d5 < y4 && y4 < u3 && u3 == u5 && x3 == l4 && l4 < r4 && r4 == x5;
}

int check_U(LineUp L6, LineLeft L7, LineUp L8) {
    
    make_LU(6);
    make_LL(7);
    make_LU(8);
    
    return getfa(L6.id) == getfa(L7.id) && getfa(L7.id) == getfa(L8.id)
    && d6==d8 && d8==y7 && y7<u6 && u6==u8 && x6==l7 && l7<r7 && r7==x8;
}

int check_P(LineUp L9, LineLeft L10, LineLeft L11, LineUp L12) {
    make_LU(9);
    make_LL(10);
    make_LL(11);
    make_LU(12);
    
    return getfa(L9.id) == getfa(L10.id) && getfa(L10.id) == getfa(L11.id) && getfa(L11.id) == getfa(L12.id)
    && d9<y11 && y11==d12 && d12<u9 && u9==y10 && y10==u12 && x9==l10 && l10==l11 && l11<r10 && r10==r11 && r11==x12;
}

int check_C(LineUp L13, LineLeft L14, LineLeft L15) {
    make_LU(13);
    make_LL(14);
    make_LL(15);
    
    return getfa(L13.id) == getfa(L14.id) && getfa(L14.id) == getfa(L15.id)
    && d13==y15 && y15<u13 && u13==y14 && x13==l14 && l14==l15 && l15<r14 && r14==r15;
}

void dfs(int stp) {
    if(stp == 5) {
        puts("Yes");
        exit(0);
    }
//    putchar(str[stp]);
    if(str[stp] == 'T') {
        for(int i = 0 ; i < ll.size() ; ++ i) {
            if(!visll[i]) {
                visll[i] = 1;
                for(int j = 0 ; j < lu.size() ; ++ j) {
                    if(!vislu[j]) {
                        vislu[j] = 1;
                        if(check_T(ll[i], lu[j])) {
                            dfs(stp + 1);
                            puts("No"); exit(0);
                        }
                        vislu[j] = 0;
                    }
                }
                visll[i] = 0;
            }
        }
    } else if(str[stp] == 'H') {
        for(int i = 0 ; i < lu.size() ; ++ i) {
            if(!vislu[i]) {
                vislu[i] = 1;
                for(int j = 0 ; j < ll.size() ; ++ j) {
                    if(!visll[j]) {
                        visll[j] = 1;
                        for(int k = 0 ; k < lu.size() ; ++ k) {
                            if(!vislu[k]) {
                                vislu[k] = 1;
                                if(check_H(lu[i], ll[j], lu[k])) {
                                    dfs(stp + 1);
                                    puts("No"); exit(0);
                                }
                                vislu[k] = 0;
                            }
                        }
                        visll[j] = 0;
                    }
                }
                vislu[i] = 0;
            }
        }
    } else if(str[stp] == 'U') {
        for(int i = 0 ; i < lu.size() ; ++ i) {
            if(!vislu[i]) {
                vislu[i] = 1;
                for(int j = 0 ; j < ll.size() ; ++ j) {
                    if(!visll[j]) {
                        visll[j] = 1;
                        for(int k = 0 ; k < lu.size() ; ++ k) {
                            if(!vislu[k]) {
                                vislu[k] = 1;
                                if(check_U(lu[i], ll[j], lu[k])) {
                                    dfs(stp + 1);
                                    puts("No"); exit(0);
                                }
                                vislu[k] = 0;
                            }
                        }
                        visll[j] = 0;
                    }
                }
                vislu[i] = 0;
            }
        }
    } else if(str[stp] == 'P') {
        for(int i = 0 ; i < lu.size() ; ++ i) {
            if(!vislu[i]) {
                vislu[i] = 1;
                for(int j = 0 ; j < ll.size() ; ++ j) {
                    if(!visll[j]) {
                        visll[j] = 1;
                        for(int k = 0 ; k < ll.size() ; ++ k) {
                            if(!visll[k]) {
                                visll[k] = 1;
                                for(int w = 0 ; w < lu.size() ; ++ w) {
                                    if(!vislu[w]) {
                                        vislu[w] = 1;
                                        if(check_P(lu[i], ll[j], ll[k], lu[w])) {
                                            dfs(stp + 1);
                                            puts("No"); exit(0);
                                        }
                                        vislu[w] = 0;
                                    }
                                }
                                visll[k] = 0;
                            }
                        }
                        visll[j] = 0;
                    }
                }
                vislu[i] = 0;
            }
        }
    } else if(str[stp] == 'C') {
        for(int i = 0 ; i < lu.size() ; ++ i) {
            if(!vislu[i]) {
                vislu[i] = 1;
                for(int j = 0 ; j < ll.size() ; ++ j) {
                    if(!visll[j]) {
                        visll[j] = 1;
                        for(int k = 0 ; k < ll.size() ; ++ k) {
                            if(!visll[k]) {
                                visll[k] = 1;
                                if(check_C(lu[i], ll[j], ll[k])) {
                                    dfs(stp + 1);
                                    puts("No"); exit(0);
                                }
                                visll[k] = 0;
                            }
                        }
                        visll[j] = 0;
                    }
                }
                vislu[i] = 0;
            }
        }
    }
    puts("No"); exit(0);
}

int fafatmp[N];

int main() {
    scanf("%d", &n);
    for(int i = 1 ; i <= n ; ++ i) {
        int op; scanf("%d", &op);
        if(op == 0) {
            int l, r, y;
            scanf("%d%d%d", &l, &r, &y);
            ll.emplace_back((LineLeft) { l, r, y, 0 });
        } else {
            int d, u, x;
            scanf("%d%d%d", &d, &u, &x);
            lu.emplace_back((LineUp) { d, u, x, 0 });
        }
    }
    sort(ll.begin(), ll.end());
    sort(lu.begin(), lu.end());
    
    cnt = 0;
    if(ll.size()) {
        vector<LineLeft> tmp;
        for(int i = 0 ; i < ll.size() ; ) {
            if(i == 0 || ll[i - 1].y != ll[i].y) {
                int j = i, y = ll[i].y;
                while(j + 1 < ll.size() && ll[j + 1].y == ll[i].y) ++ j;
                int L = ll[i].l, R = ll[i].r;
                for(int k = i ; k <= j ; ++ k) {
                    if(ll[k].l <= R) {
                        R = max(R, ll[k].r);
                    } else {
                        tmp.emplace_back((LineLeft) {L, R, y, ++ cnt});
                        L = ll[k].l, R = ll[k].r;
                    }
                }
                tmp.emplace_back((LineLeft) {L, R, y, ++ cnt});
                i = j + 1;
            } else break;
        }
        ll = tmp;
    }
    if(lu.size()) {
        vector<LineUp> tmp;
        for(int i = 0 ; i < lu.size() ; ) {
            if(i == 0 || lu[i - 1].x != lu[i].x) {
                int j = i, x = lu[i].x;
                while(j + 1 < lu.size() && lu[j + 1].x == lu[i].x) ++ j;
                int D = lu[i].d, U = lu[i].u;
                for(int k = i ; k <= j ; ++ k) {
                    if(lu[k].d <= U) {
                        U = max(U, lu[k].u);
                    } else {
                        tmp.emplace_back((LineUp) {D, U, x, ++ cnt});
                        D = lu[k].d, U = lu[k].u;
                    }
                }
                tmp.emplace_back((LineUp) {D, U, x, ++ cnt});
                i = j + 1;
            } else break;
        }
        lu = tmp;
    }
//    cout << lu.size() << ' ' << ll.size() << endl;
    if(lu.size() != 8 || ll.size() != 7) {
        puts("No");
    } else {
        
        for(int i = 1 ; i <= cnt ; ++ i) fa[i] = i;
        for(int i = 0 ; i < lu.size() ; ++ i) {
            for(int j = 0 ; j < ll.size() ; ++ j) {
                if(lu[i].d <= ll[j].y && ll[j].y <= lu[i].u
                && ll[j].l <= lu[i].x && lu[i].x <= ll[j].r) {
                    fa[getfa(lu[i].id)] = getfa(ll[j].id);
                }
            }
        }
        int tot = 0;
        for(int i = 1 ; i <= cnt ; ++ i) {
            if(getfa(i) == i) {
                ++ tot;
            }
        }
        
        if(tot == 5) {
            dfs(0);
        } else {
            puts("No");
        }
    }
//    printf("ll size = %d, lu size = %d\n", ll.size(), lu.size());
} 

K. 数正方体

// input
14 17
....+---+---+....
.../ / /|....
..+---+---+ |....
./ /| | +---+
+---+ | |/ /|
| | +---+---+ |
| |/ /| | +
+---+---+ | |/|
| | | +---+ |
| | |/ /| +
+---+---+---+ |/.
| | | | +..
| | | |/...
+---+---+---+....
// output
14


头顶标数法即可,但从上往下不太好搞,不妨从前往后 dfs,相邻两层通过 / 连接,如果一个位置是 +,并且它的左下角是空格,那么统计这个位置为一个面

#include <bits/stdc++.h>
using namespace std;

const int N = 1100;
int n, m;
char s[N][N];
int vis[N][N];
struct P {
    int x, y;
};

queue<P> que;
int cnt;
int pak[N];

void dfs(int x, int y) {
    if(vis[x][y] || !(1 <= x && x <= n && 1 <= y && y <= m)) return ;
    vis[x][y] = 1;
    if(s[x][y] == '+') {
        if(s[x][y - 1] == '-' && s[x + 1][y] == '|' && s[x + 1][y - 1] == ' ') {
            pak[cnt] ++;
        }
    }
    int mv[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    for(int i = 0 ; i < 4 ; ++ i) {
        int nx = x + mv[i][0], ny = y + mv[i][1];
        if(s[nx][ny] == '-' || s[nx][ny] == '|' || s[nx][ny] == '+') {
            dfs(nx, ny);
        }
    }
    if(s[x - 1][y + 1] == '/') {
        que.push((P) {x - 2, y + 2});
    }
}

int getfkc(char *s) {
    char c = getchar();
    while(c == '\n' || c == '\r') c = getchar();
    int t = 0;
    while(c != '\n' && c != '\r') {
        s[t ++] = c;
        c = getchar();
    }
    return t;
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1 ; i <= n ; ++ i) {
        while(!getfkc(s[i] + 1));
    }
    que.push((P) {n, 1});
    while(que.size()) {
        P fro = que.front(); que.pop();
        while(vis[fro.x][fro.y] && que.size()) {
            fro = que.front(); que.pop();
        }
        if(vis[fro.x][fro.y]) break;
        ++ cnt;
        dfs(fro.x, fro.y);
    }
    int ans = 0;
    for(int i = 1 ; i <= cnt ; ++ i) {
        ans += pak[i] * (cnt - i);
    }
    printf("%d\n", ans);
}
posted @ 2022-03-17 08:22  nekko  阅读(146)  评论(0)    收藏  举报