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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章