C,262 260
合并的代码(调试代码和不必要的空格已删除。从通过stdin的输入更改为通过命令行的输入,并利用了在此处声明变量i的机会。最新编辑:将代码移入for
循环括号中以保存两个分号。)
t[420],j,l,x,y;f(p,d){int z,q,k;for(k=6;k--;t[q]&!t[p+z]?t[q]=0,f(q,d+1),t[q]=1:0)z="AST?-,"[k]-64,q=p+z*2;l=d>l?d:l;}main(int i,char**s){for(i=840;i--;x>3&y>5&x+y<23|x<13&y<15&x+y>13?i>420?t[i-420]=49-s[1][j++]:t[i]||f(i,0):0)x=i%20,y=i/20%21;printf("%d",l);}
说明
这依赖于一个看起来像这样的20x21板,在程序启动时最初用零填充(此ASCII文字是由程序的修改版本生成的,并且随着i
循环向下计数,右下角为零):
....................
....................
...............#....
..............##....
.............###....
............####....
.......#############
.......############.
.......###########..
.......##########...
.......#########....
......##########....
.....###########....
....############....
...#############....
.......####.........
.......###..........
.......##...........
.......#............
....................
....................
循环i
遍历此板两次,使用x和y来计算正方形是否真正属于棋盘格(这需要在x和y中有6个独立的不等式。)
如果是这样,则它会在第一回合填充正方形,将0
(虚假)代表1
(占用),将1
(真实)代表0
(空闲)。这种反转非常重要,因为所有越界正方形都已经包含0,这意味着它们类似于占用的正方形,并且很明显,无需特殊检查就可以将它们跳入。
第二次,如果正方形被占用(包含0),它将调用f
搜索移动的函数。
f
在表达式中编码的+/- 1(水平),+ /-20(垂直)和+/- 19(对角线)编码的6个可能方向上递归搜索"AST?-,"[k]-64
。当找到命中时,它将在递归调用自身之前将该单元格设置为0(占用),然后在返回该函数时将其设置回1(空)。必须在递归调用之前更改单元格的值,以防止多次跳入该单元格。
非高尔夫代码
char s[999]; //input string.
t[420],i,j,l,x,y; //t=board. i=board counter, j=input counter. l=length of longest hop found so far.
f(p,d){ //p=position, d= recursion depth.
//printf("%d,%d ",p,d); //debug code: uncomment to show the nodes visited.
int k,z,q; //k=counter,z=displacement,q=destination
for(k=6;k--;) //for each direction
z="AST?-,"[k]-64, //z=direction
q=p+z*2, //q=destination cell
t[q]&!t[p+z]? //if destination cell is empty (and not out of bounds) and intervening cell is full
t[q]=0,f(q,d+1),t[q]=1 //mark destination cell as full, recurse, then mark it as empty again.
:0;
l=d>l?d:l; //if d exceeds the max recorded recursion depth, update l
}
main(){
gets(s); //get input
for(i=840;i--;) //cycle twice through t
x=i%20, //get x
y=i/20%21, //and y coordinates
x>3&y>5&x+y<23|x<13&y<15&x+y>13? //if they are in the bounds of the board
i>420?
t[i-420]=49-s[j++] //first time through the array put 0 for a 1 and a 1 for a 0 ('1'=ASCII49)
:t[i]||f(i,0) //second time, if t[i]=0,call f().
//,puts("") //puts() formats debug output to 1 line per in-bounds cell of the board
:0;
printf("%d",l); //print output
}