题意:
有一个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;
}