Knight

题目描述:

有一张无限大的棋盘,你要将马从\((0,0)\)移到\((n,m)\)。

每一步中,如果马在\((x,y)(x,y)\),你可以将它移动到 \((x+1,y+2)(x+1,y+2)\),

\((x+1,y-2)(x+1,y−2)\),\((x-1,y+2)(x−1,y+2)\),\((x-1,y-2)(x−1,y−2)\),

\((x+2,y+1)(x+2,y+1)\),\((x+2,y-1(x+2,y−1)\),\((x-2,y+1)(x−2,y+1)或(x-2,y-1)(x−2,y−1)\)。

你需要最小化移动步数。

输入:

第一行一个整数tt表示数据组数 \((1\leq t\leq 1000)\)。

每组数据一行两个整数\(n,m (|n|,|m| \leq 10^9)\)。

输出:

每组数据输出一行一个整数表示最小步数。

样例输入

2

0 4

4 2

样例输出

2

2

  • 由于数据有\(10^9\),所以BFS被毙了(~ ̄▽ ̄)~,没想到什么好的做法,所以BFS打表找规律= ̄ω ̄=。

  • 打表结果及代码

#include<iostream>
#include <queue>
using namespace std;
int dir[8][2] = {
{1,2},{1,-2},{-1,2},{-1,-2},
{2,1},{2,-1},{-2,1},{-2,-1}
};
int n, m;
int maze[1100][1100];
bool vis[1100][1100];
struct Point {
int x, y, step;
Point(int _x, int _y, int _step) :
x(_x), y(_y), step(_step) {}
};
void bfs(int sx, int sy)
{
queue<Point>q;
q.push(Point(sx, sy, 0));
vis[sx][sy] = 1;
maze[sx][sy] = 0;
while (!q.empty())
{
int x = q.front().x;
int y = q.front().y;
int step = q.front().step;
maze[x][y] = step;
q.pop();
for (int i = 0; i < 8; i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if (!vis[tx][ty]&&tx<61&&ty<61&&tx>=0&&ty>=0)
{
q.push(Point(tx, ty, step + 1));
vis[tx][ty] = 1;
}
}
}
}
int main() {
//freopen("1.txt", "w", stdout);
bfs(30, 30);
for (int i = 0; i < 60; i++) {
for (int j = 0; j <60; j++) {
cout << maze[i][j] << " ";
}
cout << endl;
}
return 0;
}
  • 从上面看,很明显是有规律的,据说大佬能一眼就看出来,以前我是不信的,直到现场有dalao花了4分钟拿了一血……<@_@>蒟蒻只能慢慢推了。首先先把上面的数据放到Excel里面,先预处理一下,将每个答案作为点,以起点为原点建立平面直角坐标系,结果如下:

之前我犯了一个错误,BFS起点放到数组边界上去了,应该放到偏中心的位置,把表打出来。将答案统一起来看,从2开始,所有相同的答案围成了一个八边形,这个八边形与坐标轴平行的边都是4层,不平行的都是3层,同时答案基本是向外递增的这样看的时候会发现两个特殊的地方,一个是\((0,1),(1,0),(-1,0),(0,-1)\)这四个点为3,\((2,0),(0,2),(0,-2),(-2,0)\)着四个点4,所以将这些点加入特判。

不难看出,这个表关于坐标轴对称(图中蓝色线),同时也关于\(y=+-x\)对称(图中橙色线),所以\(x\)轴正半轴为起点,逆时针划分为8个区域,每个区域都一样,只需要考虑1号区域就行了。

现在考虑的为1号区域,希望找到递增的答案之间存在的关系,这个关系为\(y=x/2\),可以发现这条直线上的整点正好是答案的递增:\(0,0)->(2,1)->(4,2).....->(x,floor(x/2))\)。将这条直线画出来。(floor()是对一个数值向下取整)

现在看\(y=x/2\)下方的点,满足关系\(y<x/2\),也就是\(y<x-y\)(精度问题,计算时应该用double),而且下方的点都是在刚才所说的八边形的4层边上,所以可以发现将这些点作如下变换后可以将横坐标和\(y=x/2\)对应:

double(x-y-y)/4.0*2;

最后将上面这个值取反\(+x-y\)就是答案。同理可以推出\(y=x/2\)上方的点,满足关系\(y>x/2\),在刚才所说的八边形的3层边上,最后推出

double(x-y-y)/3.0*2;
  • Code
#include <cstdio>
#include <cstring>
#include <cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
ll fun(ll x, ll y) { if (x == 1 && y == 0) {
return 3;
}
if (x == 2 && y == 2) {
return 4;
}
ll delta = x - y;
if (y>delta) {
return delta - 2 * floor(((double)(delta-y)) / 3.0);
}
else {
return delta - 2 * floor(((double)(delta-y)) / 4.0);
}
} int main()
{ int t;
cin >> t;
while (t--)
{
ll x, y;
cin >> x >> y;
x = abs(x);
y = abs(y);
if (x < y) {
swap(x, y);
}
cout << fun(x, y) << endl;
} return 0;
}
  • 最后,为正经题解

    Knight:

    不妨假设\(x>=y>=0\)。

    当\(x<=2y\) 时,定义每一步的冗余值\(w_i=3-dx-dy\),那么\(Σw_i=Σ(2-dx)=3*步数-x-y\),显然我们只需要最小化冗余值。我们先只用(+2,+1)(若x 为奇数则加一步(+1,+2))走到(x,y’),然后通过将(+2,+1)替换为2 个(+1,+2)使得\(0<=y-y’<3\)。

    若\(y-y’=0\),则冗余值为0,显然最小。

    若\(y-y’=1\),则将(+1,+2)替换为(+2,+1)和(-1,+2)或将2 个(+2,+1)替换为(+1,+2),(+1,+2),(+2,-1),冗余值为2,显然最小。(此处需要特判(2,2))

    若\(y-y’=2\),则加上\((+2,+1)和(-2,+1)\),冗余值为4,由于不存在冗余值为1的步,所以最小。

    当\(x>2y\) 时,定义每一步的冗余值\(w_i=2-dx\),那么\(Σw_i=Σ(2-dx)=2*步数-x\),显然我们只需要最小化冗余值。我们先只使用(+2,+1)走到(2y,y),然后用

    (+2,+1)和(+2,-1)走到\((x’,y)使得0<=x-x’<4\)。

    若\(x-x’=0\)则冗余值为0,显然最小。

    若\(x-x’=1\) 则将之前的(+2,+1)改为(+1,+2)和(+2,-1),冗余值为1,显然最

    小。(此处需要特判(1,0))若\(x-x’=2\) 则加上(+1,+2)和(+1,-2),冗余值为2,由x/2+y 的奇偶性可知

    最小。

    若\(x-x’=3\) 则加上(+2,+1),(+2,+1),(-1,-2),冗余值为3,由x/2+y 的奇偶性可知最小。

    时间复杂度O(t)

2018 Wannafly summer camp Day3--Knight的更多相关文章

  1. 2018 Wannafly summer camp Day8--连通块计数

    连通块计数 描述 题目描述: 小 A 有一棵长的很奇怪的树,他由 n 条链和 1 个点作为根构成,第 i条链有 ai​ 个点,每一条链的一端都与根结点相连. 现在小 A 想知道,这棵长得奇怪的树有多少 ...

  2. 2018 Wannafly summer camp Day2--Utawarerumono

    Utawarerumono 描述 题目描述: 算术是为数不多的会让久远感到棘手的事情.通常她会找哈克帮忙,但是哈克已经被她派去买东西了.于是她向你寻求帮助. 给出一个关于变量x,y的不定方程ax+by ...

  3. 2018 Wannafly summer camp Day2--New Game!

    New Game! 描述 题目描述: Eagle Jump公司正在开发一款新的游戏.泷本一二三作为其员工,获得了提前试玩的机会.现在她正在试图通过一个迷宫. 这个迷宫有一些特点.为了方便描述,我们对这 ...

  4. 2018 Wannafly summer camp Day8--区间权值

    区间权值 小Bo有\(n\)个正整数\(a_1\)--\(a_n\),以及一个权值序列\(w_1\)--\(w_n\),现在她定义\(f(l,r)=(\sum_{i=l}^r a_i^2) *w_{r ...

  5. 2018 Wannafly summer camp Day3--Shopping

    Shopping 描述 题目描述: 你要买n件物品,其中有一些是凳子. 商场正在举行促销活动,如果购物车中有至少一个凳子,那么你可以半价购买这个购物车中最贵的一个物品. 你有m辆购物车,请最小化你的花 ...

  6. 2018 Wannafly summer camp Day3--Travel

    Travel 描述 题目描述: 魔方国有n座城市,编号为1~n.城市之间通过n-1条无向道路连接,形成一个树形结构. 澜澜打算在魔方国进行mm次旅游,每次游览至少一座城市.为了方便,每次旅游游览的城市 ...

  7. 2019 wannafly winter camp

    2019 wannafly winter camp Name Rank Solved A B C D E F G H I J K day1 9 5/11 O O O O O day2 5 3/11 O ...

  8. 2019 wannafly winter camp day 3

    2019 wannafly winter camp day 3 J 操作S等价于将S串取反,然后依次遍历取反后的串,每次加入新字符a,当前的串是T,那么这次操作之后的串就是TaT.这是第一次转化. 涉 ...

  9. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

随机推荐

  1. typeScript入门(三)接口

      接口我感觉是很常用的一块 定义标准: 接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用.接口定义了某一批类所需要遵守的规 ...

  2. Please, configure Web Facet first!idea报这错的解决办法!!

    Please, configure Web Facet first!idea报这错的解决办法!! 今天在idea导入用eclipse的项目,然后运行项目的时候报这个错, 看下图 网上找了好多都没解决, ...

  3. 支持触屏的zepto轮播图插件

    占个座,有时间再写,呵呵 关于zepto.js,官方标准版是不支持touch的.可以去github下载压缩包,里面有所有支持的模块.我用的zepto.js,是经过打包的,包括polyfill zept ...

  4. iDempiere 使用指南 绿色版一键启动测试环境

    Created by 蓝色布鲁斯,QQ32876341,blog http://www.cnblogs.com/zzyan/ iDempiere官方中文wiki主页 http://wiki.idemp ...

  5. Sharepoint日志文件增长巨大的解决办法/缩小日志/删除日志

    前段时间为公司开发部门建立了TFS平台,其中包括WSS3(MOSS07也可,但是如果不是必须,建议使用轻量级的WSS3).TFS建成之后,程序员们用起来都很满意,总监也很关注. 但是今天早上忽然发现连 ...

  6. CSS中的EM属性之弹性布局

    这篇教程将引导大家如何使用“em”来创建一个基本的弹性布局,从而学习其如何计算?又是如何使用“em”对层进行弹性扩展?又是如何扩展文本和图像等内容?下在我们就一起带着这些问题开始今天的“em”之行. ...

  7. March 5 2017 Week 10 Sunday

    If you do what you love, you will never work a day in your life. 做你所爱的事情,你就不会觉得是在工作. Today, one mach ...

  8. python入门22 pymssql模块(python连接sql server查询)

    安装 pip install pymssql 连接数据库 pymssql.connect() # coding:utf-8 import pymssql server = '192.168.8.1' ...

  9. Android获取手机安装的浏览器列表

    最近碰到一个同事询问如何查询本地安装的浏览器列表,其使用的代码如下: public static List<ResolveInfo> getBrowserList(Context cont ...

  10. Codeforces Round #375 (Div. 2) D. Lakes in Berland (DFS或并查集)

    D. Lakes in Berland time limit per test 2 seconds memory limit per test 256 megabytes input standard ...