我是竞争性编程的新手,我经常注意到,许多伟大的编码员在他们的代码中都有这四行(特别是那些涉及数组的代码):
int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int diK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
int djK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };
Run Code Online (Sandbox Code Playgroud)
这真正意味着什么,技术用于什么?
Pat*_*shu 84
这是一种将所有方向编码为数组的技术 - 每对di[i],dj[i]
都是不同的方向.
如果我们想象我们在x,y位置有一块,我们想要添加到它的x及其y值以将其移动到附近的位置,1,0是东,-1,0是西,0,1南,0,-1是北,依此类推.
(这里我说左上角是0,0,右下角是4,4,显示了数组的每个索引将从中心点X移动到2.2.)
.....
.536.
.1X0.
.724.
.....
Run Code Online (Sandbox Code Playgroud)
它的设置方式,如果你在索引上做^1
(^
按位XOR)你会得到相反的方向 - 0和1是对立的,2和3是对立的,依此类推.(设置它的另一种方法是从北方开始顺时针方向 - 然后^4
让你朝相反的方向前进.)
现在你可以通过遍历你的di
和dj
数组来测试给定点的所有方向,而不是需要在它自己的行上写出每个方向(总共八个!)(只是不要忘记做边界检查:))
diK
并djK
形成所有骑士的方向,而不是所有相邻的方向.在这里,^1
将沿一个轴翻转,^4
将给予相反的骑士飞跃.
.7.6.
0...5
..K..
1...4
.2.3.
Run Code Online (Sandbox Code Playgroud)
Jam*_*ess 64
对于那些发现Patashu的解释难以理解的人,我将试图澄清.
想象一下,你正试图从国际象棋棋盘上的特定点考虑每一个可能的移动.
如果循环遍历di和dj数组,将di值解释为x偏移量并将dj值解释为y偏移量,则覆盖每个可能的8个方向.
假设正x是东,正y是南(如Patashu的答案),你得到以下结果;
| di/x | dj/y | Direction --+------+------+----------- 0 | 1 | 0 | east 1 | -1 | 0 | west 2 | 0 | 1 | south 3 | 0 | -1 | north 4 | 1 | 1 | south-east 5 | -1 | -1 | north-west 6 | 1 | -1 | north-east 7 | -1 | 1 | south-west
diK和djK数组的解释方式可以相同,以确定Knight作品的可能移动.如果你不熟悉国际象棋,骑士会以L模式移动 - 一个方向上有两个正方形,然后是一个与之成直角的正方形(反之亦然).
| diK/x | djK/y | Direction --+-------+-------+---------------- 0 | -2 | -1 | 2 west, 1 north 1 | -2 | 1 | 2 west, 1 south 2 | -1 | 2 | 1 west, 2 south 3 | 1 | 2 | 1 east, 2 south 4 | 2 | 1 | 2 east, 1 south 5 | 2 | -1 | 2 east, 1 north 6 | 1 | -2 | 1 east, 2 north 7 | -1 | -2 | 1 west, 2 north