2019 Multi-University Training Contest 8 :Acesrc and Hunting 1004(暴搜)

Problem Description

Acesrc is a famous hunter at Nanjing University second to none. Recently, he set n×m traps in Yangshan Park, a park near Nanjing University Xianlin Campus, arranged in n rows and m columns. The rows are numbered 1 through n from bottom to up, and the columns are numbered 1 through m from left to right. The distance between two adjacent traps, both horizontally and vertically, is 1 meter.

Today, Acesrc happily finds that every trap he set has captured an animal. He decides to collect these hunted animals to make roast meat for his friends. However, collecting these animals normally is too boring, so he decides to find a route following the rules below:

1. Acesrc can choose any trap to start; every time he collects the animal in the trap, he moves to some unvisited trap and repeats until all captured animals are collected;
2. The Euclidean distance he moves from one trap to the next trap should be between 1 meter and 3 meters exclusive; that is, the distance should be strictly greater than 1 meter and strictly less than 3 meters.

Acesrc has quickly collected all animals. Roo wonders how Acesrc collected these animals, but Acesrc buttons up his lip. Can you give a possible route to collect all the animals?

Input

The first line of input consists of a single integer T (1≤T≤240), the number of test cases. Each test case is a single line of two integers n,m (1≤n,m≤100), denoting the size of the trap matrix.

Output

For each test case, if it is impossible to find any valid route, print NO in a single line; otherwise, print YES in one line, followed by n×m lines describing the route, each of these lines containing two integers x,y (1≤x≤n,1≤y≤m), denoting the position of a trap visited. If multiple solutions exist, print any.

 

Sample Input

2 2 2 2 3

Sample Output

NO YES 1 1 2 2 1 3 2 1 1 2 2 3

Source

2019 Multi-University Training Contest 8

题意:有n * m 个trap,你可以从任意trap出发,下一步只能走欧拉距离小于3大于1的trap,问是否能走完所有trap,如果能输出路径(spj)。

题解:对于不能走完的情况,我们只需要特判一下(只有几种)就行了。如果能走完,那么无论从哪个点出发都能满足,所以我们可以随便从一个点出发进行dfs暴搜,在暴搜的时候小小的贪心一下:在下一步有多种选择的时候,我们选择后继点少的那个点作为下一步的位置。

#include "bits/stdc++.h"
#include<iostream>
#include<sstream>
#include<iterator>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<vector>
#include<bitset>
#include<climits>
#include<queue>
#include<iomanip>
#include<cmath>
#include<stack>
#include<map>
#include<ctime>
#include<new>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define MT(a,b) memset(a,b,sizeof(a))
const int INF  =  0x3f3f3f3f;
const int O    =  1e6;
const int mod  =  1e6 + 3;
const int maxn =  1e2 + 5;
const double PI  =  acos(-1.0);
//const double E   =  2.718281828459;
const double eps = 1e-7;

int run[6][2] = {2, 0, 1, 1, 1, 2, 2, 1, 0, 2, 2, 2};
int op[4][2] = {1, 1, -1, 1, 1, -1, -1, -1};
int vis[maxn][maxn], n, m, k =0;
bool flag = false;

bool check(int x, int y) { return x < 0 || y < 0 || x >= n || y >= m; }

int get_cnt(int x, int y) {
    int ans = 0;
    for(int i=0; i<6; i++) {
        for(int j=0; j<4; j++) {
            int xx = x + run[i][0] * op[j][0];
            int yy = y + run[i][1] * op[j][1];
            if (check(xx, yy) || vis[xx][yy]) continue;
            ans++;
        }
    }
    return ans;
}

void dfs(int x, int y) {
    vis[x][y] = 1; k ++;
    if(flag) printf("%d %d\n", y + 1, x + 1);
    else printf("%d %d\n", x + 1 , y + 1);
    int MIN = INF, tx, ty;
    for(int i=0; i<6; i++) {
        for(int j=0; j<4; j++) {
            int xx = x + run[i][0] * op[j][0];
            int yy = y + run[i][1] * op[j][1];
            if (vis[xx][yy]) continue;
            if (check(xx, yy)) continue;
            int cnt = get_cnt(xx, yy);
            if (cnt < MIN) MIN = cnt, tx = xx, ty = yy;
        }
    }
    if(MIN != INF) dfs(tx, ty);
}

int main() {
    int T; cin >> T;
    while (T--) {
        MT(vis, 0);
        cin >> n >> m;
        k = 0; flag = false;
        if (m < n) { swap(n, m); flag = true; }
        if (n == 1 && m == 1) { printf("YES\n1 1\n"); continue; }
        if (n < 2 || m < 3) { printf("NO\n"); continue; }
        printf("YES\n");
        dfs(0, 0);
        //printf("%d\n", k);
    }
    return 0;
}

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值