題意:
有一個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;
}