King's Tour

题面大意

在 \(n\times m\) 的网格中构造一种从 \((1,1)\) 走到 \((a,b)\) 的方案,要求经过所有格子恰好一次,格子之间八联通。

思路分析

模拟赛题,赛时写了一个半小时过了(

思路不是很复杂,但是需要一些分类讨论。


  • 引理:对于任意大小的矩形,一定存在从左上走到右下的方案。

  • 证明:

若长宽中有一个是奇数,那么我们可以按照如下方案构造:

否则,我们可以按照如下方案构造:


那么同理,我们只需要将矩形翻转就可以得到从矩形一个角走到对角的方案。

walk(x1, y1, x2, y2) 表示输出从 \((x_1,y_1)\) 走到 \((x_2,y_2)\),填满以 \((x_1,y_1)\) 和 \((x_2,y_2)\) 作为对角线的矩形的方案。

而当我们考虑从 \((1,1)\) 走到 \((a,b)\) 时,我们进行分类讨论,下面是图示和代码实现:

(蓝色边表示用引理的方案填满整个矩形,绿色边表示实际走的边。)

  • \(a=n,b=m\):

walk(1, 1, a, b)
  • \(a=1,b=m\):

walk(1, 1, n, m - 1);
walk(n, m, a, b);
  • \(a=n,b=1\):

walk(1, 1, n - 1, m);
walk(n, m, a, b);
  • \(a=1,b\not =m\):

walk(1, 1, n, b - 1);
walk(n, b, 2, m);
walk(1, m, a, b);
  • \(b=1,a\not =n\):

walk(1, 1, a - 1, m);
walk(a, m, n, 2);
walk(n, 1, a, b);
  • \(a=n,b\not =1\):

walk(1, 1, n, b - 1);
walk(n - 1, b, 1, b);
walk(1, b + 1, n - 1, m);
walk(n, m, a, b);
  • \(b=m,a\not =1\):

walk(1, 1, a - 1, m);
walk(a, m - 1, n - 1, 1);
walk(n, 1, n, m);
walk(n - 1, m, a, b);
  • \(a\in[2,n-1],b\in[2,m-1]\):

walk(1, 1, a - 1, m);
walk(a, m, n, b + 1);
walk(n, b, a + 1, 1);
walk(a, 1, a, b);

那么这题就愉快的结束了,时间复杂度显然是 \(O(n^2)\)。

代码

(109 行,3.5k)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath> using namespace std;
const int N = 200200;
#define inf 0x3f3f3f3f int n, m, a, b; namespace SOL{
void walk(int x1, int y1, int x2, int y2){
int dir;
if (x1 <= x2 && y1 <= y2) dir = 1;
if (x1 > x2 && y1 <= y2) dir = 3;
if (x1 <= x2 && y1 > y2) dir = 2;
if (x1 > x2 && y1 > y2) dir = 4;
if (x1 > x2) swap(x1, x2);
if (y1 > y2) swap(y1, y2);
int n = x2 - x1 + 1, m = y2 - y1 + 1;
vector <pair<int, int>> v;
if ((n & 1) || (m & 1)) {
if (n & 1) {
int x = 1, y = 0, d = 1;
for (int i = 1; i <= n * m; i ++) {
y += d;
if (y == m + 1) y = m, x ++, d = -d;
if (y == 0) y = 1, x ++, d = -d;
v.push_back({x, y});
}
}
else {
int x = 0, y = 1, d = 1;
for (int i = 1; i <= n * m; i ++) {
x += d;
if (x == n + 1) x = n, y ++, d = -d;
if (x == 0) x = 1, y ++, d = -d;
v.push_back({x, y});
}
}
}
else {
int x = 1, y = 0, d = 1;
for (int i = 1; i <= (n - 2) * m; i ++) {
y += d;
if (y == m + 1) y = m, x ++, d = -d;
if (y == 0) y = 1, x ++, d = -d;
v.push_back({x, y});
}
for (int i = 1; i <= m; i ++) {
v.push_back({n - 1, i});
v.push_back({n, i});
}
}
if (dir == 2) for (auto &it : v) it.second = m - it.second + 1;
if (dir == 3) for (auto &it : v) it.first = n - it.first + 1;
if (dir == 4) for (auto &it : v) it.first = n - it.first + 1, it.second = m - it.second + 1;
for (auto it : v) cout << it.first + x1 - 1 << ' ' << it.second + y1 - 1 << '\n';
}
void work(){
if (a == n && b == m) {
walk(1, 1, n, m);
}
else if (a == n && b == 1) {
walk(1, 1, n - 1, m);
walk(n, m, a, b);
}
else if (a == 1 && b == m) {
walk(1, 1, n, m - 1);
walk(n, m, a, b);
}
else if (a == 1) {
walk(1, 1, n, b - 1);
walk(n, b, 2, m);
walk(1, m, a, b);
}
else if (b == m) {
walk(1, 1, a - 1, m);
walk(a, m - 1, n - 1, 1);
walk(n, 1, n, m);
walk(n - 1, m, a, b);
}
else if (a == n) {
walk(1, 1, n, b - 1);
walk(n - 1, b, 1, b);
walk(1, b + 1, n - 1, m);
walk(n, m, a, b);
}
else if (b == 1) {
walk(1, 1, a - 1, m);
walk(a, m, n, 2);
walk(n, 1, a, b);
}
else {
walk(1, 1, a - 1, m);
walk(a, m, n, b + 1);
walk(n, b, a + 1, 1);
walk(a, 1, a, b);
}
}
} int main(){
scanf("%d %d %d %d", &n, &m, &a, &b);
return SOL::work(), 0;
}

King's Tour 题解的更多相关文章

  1. POJ2135:Farm Tour——题解

    http://poj.org/problem?id=2135 题目大意: 从1到n再回来,每条边只能走一次,问最短路. —————————————————— 如果不告诉我是费用流打死不会想这个…… 我 ...

  2. LuoguP7041 [NWRRC2016]King's Heir 题解

    Content 给出现在的日期,请从 \(n\) 个人当中选出一个人,使得他是所有成年人(\(\geqslant 18\) 岁的人)中年龄最小的. 数据范围:设日期为 \(yy/mm/dd\),则有 ...

  3. M-SOLUTIONS Programming Contest 2021(AtCoder Beginner Contest 232) 题解

    目录 G - Modulo Shortest Path H - King's Tour 因为偷懒就只写G和H的题解了. G - Modulo Shortest Path 首先可以观察到对于一条从点\( ...

  4. ACM - 动态规划 - UVA 1347 Tour

    UVA 1347 Tour 题解 题目大意:有 \(n\) 个点,给出点的 \(x\).\(y\) 坐标.找出一条经过所有点一次的回路,从最左边的点出发,严格向右走,到达最右点再严格向左,回到最左点. ...

  5. [COGS 2583]南极科考旅行

    2583. 南极科考旅行 ★★   输入文件:BitonicTour.in   输出文件:BitonicTour.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 小美要 ...

  6. 【题解】Sigitseeing Tour

    题目大意 有一张$n$个结点,$m$条混合边的图($1 \leq n \leq 200$,$1 \leq m \leq 1000$),求这张图是否存在欧拉回路. 题解 因为有混合边,所以我们要先给无向 ...

  7. World Tour Finals 2019 D - Distinct Boxes 题解

    太神了,专门写一篇题解 qwq 简要题意:给你 \(R\) 个红球和 \(B\) 个蓝球,你要把它们放到 \(K\) 个箱子里,要求没有两个箱子完全相同(即两种球个数就相同),求 \(K\) 的最大值 ...

  8. Money King【题解】

    我又傻了……竟然忘了区别大根堆和小根堆的性质,以至于一个符号打错,debug了半天……(我真是太菜了……) 题目描述 Once in a forest, there lived N aggressiv ...

  9. POJ 1904 King's Quest(强连通图)题解

    题意:n个王子有自己喜欢的ki个公主,有n个公主,每个王子只能娶一个自己喜欢的公主且不能绿别的王子.现在给你一种王子娶公主的方案,并且保证这种方案是正确的.请你给出,每个王子能娶哪些公主,要求娶这些公 ...

  10. POJ2728:Desert King——题解

    http://poj.org/problem?id=2728 题目大意:求一棵生成树使得路费用和/路长之和最小(路的费用是两端点的高度差) 最小比率生成树. 我们还是01分数规划的思想将边权变为路费用 ...

随机推荐

  1. 即构SDK8月迭代:新增下行网络测速、切换房间、预览首帧回调等多项功能

    即构SDK8月上新,网络探测模块新增下行网络测速.媒体播放器新增缓存到文件结尾的回调.新增切换房间功能.新增预览首帧回调等.本月SDK迭代新上线的功能非常丰富,详细内容请看下文. LiveRoom 新 ...

  2. webshell工具流量特征

    常见的webshell管理工具及流量特征 菜刀 作为老牌 Webshell 管理神器,中国菜刀的攻击流量特征明显,容易被各类安全设备检测,实际场景中越来越少使用,加密 Webshell 正变得日趋流行 ...

  3. 前后端分离实现注册+登录(Vue3.0 + Django3.2)

    博客地址:https://www.cnblogs.com/zylyehuo/ 一.使用 vite+webstorm 搭建 Vue 环境,构建前端 1.结构树 2.main.js import { cr ...

  4. 使用Stable Diffusion制作AI数字人视频的简明教程

    基本方法 搞一张照片,搞一段语音,合成照片和语音,同时让照片中的人物动起来,特别是头.眼睛和嘴. 语音合成 语音合成的方法很多,也比较成熟了,大家可以选择自己方便的,直接录音也可以,只要能生成一个语音 ...

  5. 烧死10亿脑细胞的SQL长啥样?

    1 前言 今天在生产中碰到了一个让我十分费解的 SQL,十分有趣. 2 现象 SQL 很好复现,就是逻辑看起来有点唬人 postgres=# create table test(id1 int,id2 ...

  6. spring-mvc系列:详解@RequestMapping注解(value、method、params、header等)

    目录 一.@RequestMapping注解的功能 二.@RequestMapping注解的位置 三.@RequestMapping注解的value属性 四.@RequestMapping注解的met ...

  7. 记一次因为C#官方扩展导致自动补全出错的情况 (C# & Godot)

    现象 最近使用Vscode结合Godot使用时突然发现自动补全出问题了,发现一部分自动补全能弹出补全项目,但是确认后不起作用,还会吞掉弹出自动补全后输入的字符.大概是下图这样的感觉(截图时已修好,图为 ...

  8. Linux下发现一个高安全性的系统管理工具

    软件 AnySetup 主要功能 主要功能是对Linux操作系统下的基本配置进行管理.多种服务配置进行管理.安全配置进行管理等.如:操作系统的升级管理,软件包的安装.更新和卸载管理,软件仓库源的管理, ...

  9. Python 潮流周刊#16:优雅重要么?如何写出 Pythonic 的代码?

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中两则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...

  10. 一行命令即可启动 Walrus丨入门教程

    应用管理平台 Walrus 已正式开源,本文将介绍如何上手安装 Walrus 以及如何借助 Walrus 进行应用部署. 开源地址:https://github.com/seal-io/walrus ...