2019 hdu 多校8 Acesrc and Hunting(构造)

链接

题意:

有一个n*m的矩阵,有一个人,这个人要走遍每个格子。规则如下:
1.每个格子只能到达一次;
2.下一步要走的格子到当前这个格子的距离在(1,3)内,不包括1和3。



题解:

不能走遍所有格子的情况有 n=1且m!=1 ,n!=1且m=1 以及 n=2且m=2
对于n=1 m=1的情况直接特判
剩下的情况需要构造方案。

首先默认m>=n,如果m<n则swap一下(swap的话最后的答案要再反回来)

跟官方题解中的图差不多
想想还是比较简单的,只要前两行特殊处理一下,下面的都是很规律的。但是写起来还是比较麻烦,我的做法是用个双端队列,先放如左上(1,1)到(2,2),然后用个while循环走完第二行再回到第一行。差不多也是一个while循环走到(1,3),然后特殊地放入(2,1)到(1,2)然后while循环把第一行和第二行剩下的全部放入,最后到第三行,在第三的位置需要根据m的奇偶性判断一下。后面差不多用dfs之类的就可以搞定。然后再考虑(1,1)之前的位置,前一个是第三行的第一个,然后也是一个dfs推一下就好了,这里要从双端队列的前面插。

参考代码:

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
deque<pii> q;
int n, m;

void dfs1(int x, int y) {
    if(x>n)return;
    if (x & 1) {
        int now = y;
        while (now - 2 > 0) {
            now -= 2;
            q.push_back({x, now});
        }
        if (x == n)
            return;
        int dy = 0;
        if (now == 2) {
            dy = 1;
            q.push_back({x + 1, 1});
        } else {
            dy = 2;
            q.push_back({x + 1, 2});
        }
        dfs1(x + 1, dy);
    } else {
        int now = y;
        while (now + 2 <= m) {
            now += 2;
            q.push_back({x, now});
        }
        if (x == n)
            return;
        int dy = 0;
        if (now == m) {
            dy = m - 1;
            q.push_back({x + 1, m - 1});
        } else {
            dy = m;
            q.push_back({x + 1, m});
        }
        dfs1(x + 1, dy);
    }
}

void dfs2(int x, int y) {
    if(x>n)return;
    if (x & 1) {
        int now = y;
        while (now + 2 <= m) {
            now += 2;
            q.push_front({x, now});
        }
        if (x == n)
            return;
        int dy = 0;
        if (now == m) {
            dy = m - 1;
            q.push_front({x + 1, m - 1});
        } else {
            dy = m;
            q.push_front({x + 1, m});
        }
        dfs2(x + 1, dy);
    } else {
        int now = y;
        while (now - 2 > 0) {
            now -= 2;
            q.push_front({x, now});
        }
        if (x == n)
            return;
        int dy = 0;
        if (now == 1) {
            dy = 2;
            q.push_front({x + 1, 2});
        } else {
            dy = 1;
            q.push_front({x + 1, 1});
        }
        dfs2(x + 1, dy);
    }
}

int main() {
    int t;
    scanf("%d", &t);
    for (int ca = 1; ca <= t; ca++) {
        q.clear();
        scanf("%d%d", &n, &m);
        if(n==1&&m==1){
            printf("YES\n1 1\n");
            continue;
        }
        if ((n == 1 && m != 1) || (n != 1 && m == 1) || (n == 2 && m == 2)) {
            printf("NO\n");
        } else {
            bool turn=n>m;
            if(turn){
                swap(n,m);
            }
            printf("YES\n");
            q.push_back({1, 1});
            q.push_back({2, 2});
            int now = 2;
            while (now+2<= m) {
                now += 2;
                q.push_back({2, now});
            }
            if (m & 1) {
                now = m;
                q.push_back({1, m});
            } else {
                now = m - 1;
                q.push_back({1, m - 1});
            }
            while (now - 2 >= 3) {
                now -= 2;
                q.push_back({1, now});
            }
            q.push_back({2, 1});
            now = 2;
            int tp = 1;
            while (now <= m) {
                if (tp) {
                    q.push_back({1, now});
                } else {
                    q.push_back({2, now});
                }
                now++;
                tp ^= 1;
            }
            if(n!=2){
                q.push_front({3, 1});
                int y = 0;
                if (m & 1) {
                    y = m - 1;
                    q.push_back({3, m - 1});
                } else {
                    y = m;
                    q.push_back({3, m});
                }
                dfs1(3, y);
                dfs2(3, 1);
            }
            while (!q.empty()) {
                pii x = q.front();
                q.pop_front();
                if(turn){
                    printf("%d %d\n", x.second,x.first);
                }
                else{
                    printf("%d %d\n", x.first,x.second);
                }
            }
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章