Любой, кто знаком с проблемой подсчета путей вверх/вправо в прямоугольнике из нижнего левого угла в верхний правый угол, знает, что один из способов сделать это — сделать это с помощью рекурсии. Я хочу визуализировать это, и поэтому мне нужно создать решетку, в вершинах которой есть числа. В следующей матрице числа находятся внутри квадратов, но я хочу, чтобы они были в вершинах или, что еще лучше, чтобы был зазор в пересечении четырех линий, и число могло бы быть в этом зазоре.
$\begin{array}{*{20}{c}}
\hline
| & 1&| & 1&| & 1&| & 1&| & 1&| & 1&| & 1| & \\
\hline
| & 7&| & 6&| & 5&| & 4&| & 3&| & 2&| & 1| & \\
\hline
| & {28}&| & {21}&| & {15}&| & {10}&| & 6&| & 3&| & 1| & \\
\hline
| & {84}&| & {56}&| & {35}&| & {20}&| & {10}&| & 4&| & 1| & \\
\hline
\end{array}$
Что-то вроде этого:
Важное примечание: Изображение было отредактировано после того, как на вопрос был дан правильный ответ с помощью изображения.
решение1
Вот как это сделать:
Код:
\documentclass{article}
\usepackage{xstring}
\usepackage{tikz}
\usepackage{collcell}
\newcommand{\MakeBox}[1]{\makebox[2.0em][c]{#1}}%
\newcommand*{\MyBox}[1]{%
\phantom{\MakeBox{#1}}%
\IfStrEq{#1}{}{}{%
\begin{tikzpicture}[overlay, draw=red, line width=1.0pt, text=blue]
\node [draw=none, inner sep=2pt] (Node) {\MakeBox{#1}};
\draw (Node.north) -- ([yshift=2.0ex]Node.north);
\draw (Node.south) -- ([yshift=-2.0ex]Node.south);
\draw (Node.west) -- ([xshift=-1.0em]Node.west);
\draw (Node.east) -- ([xshift=1.0em]Node.east);
\end{tikzpicture}%
}%
}
\newcolumntype{C}{>{\collectcell\MyBox}c<{\endcollectcell}}
\begin{document}
$\begin{array}{*{20}{C}}
& 1 & 1 & 1 & 1 & 1 & 1 & 1 & \\[2.0ex]
& 7 & 6 & 5 & 4 & 3 & 2 & 1 & \\[2.0ex]
& 28 & 21 & 15 & 10 & 6 & 3 & 1 & \\[2.0ex]
& 84 & 56 & 35 & 20 & 10 & 4 & 1 & \\ [2.0ex]
\end{array}$
\end{document}
Если вы хотите подавить внешние линии, то вам нужно указать последнюю строку с помощью вызова \ThisIsLastRow
. Обнаружение первого столбца обрабатывается с помощью F
типа столбца.
Дальнейшие улучшения
- Так как я использую a
\makebox[2.0em][c]{#1}
для размещения текста, чтобы он оставался центрированным, то последний столбец, который содержит только символы одинарной ширины, выглядит неправильно. Один из способов исправить это — определить два типа столбцов: один для двузначных цифр и один для однозначных цифр. В качестве альтернативы можно нарисовать линии через текст, а затем наложить на него текст узла, что затем удалит линии только вокруг цифр.
Код:
\documentclass{article}
\usepackage{xstring}
\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{collcell}
\newtoggle{IsFirstColumn}\togglefalse{IsFirstColumn}%%
\newtoggle{IsLastRow}\togglefalse{IsLastRow}%
\newcommand{\ThisIsLastRow}{\global\toggletrue{IsLastRow}}%
\newcommand{\MakeBox}[1]{\makebox[2.0em][c]{#1}}%
\newcommand*{\MyBox}[1]{%
\phantom{\MakeBox{#1}}%
\IfStrEq{#1}{}{}{%
\begin{tikzpicture}[overlay, draw=red, line width=1.0pt, text=blue]
\node [draw=none, inner sep=2pt] (Node) {\MakeBox{#1}};
\iftoggle{IsLastRow}{}{%
\draw (Node.south) -- ([yshift=-2.0ex]Node.south);
}%
\iftoggle{IsFirstColumn}{}{%
\draw (Node.west) -- ([xshift=-1.0em]Node.west);
}%
\end{tikzpicture}%
}%
}
\newcommand*{\MyBoxFirstColumn}[1]{%
\global\toggletrue{IsFirstColumn}%
\MyBox{#1}%
\global\togglefalse{IsFirstColumn}%
}%
\newcolumntype{C}{>{\collectcell\MyBox}c<{\endcollectcell}}
\newcolumntype{F}{>{\collectcell\MyBoxFirstColumn}c<{\endcollectcell}}
\begin{document}
$\begin{array}{F*{20}{C}}
1 & 1 & 1 & 1 & 1 & 1 & 1 \\[2.0ex]
7 & 6 & 5 & 4 & 3 & 2 & 1 \\[2.0ex]
28 & 21 & 15 & 10 & 6 & 3 & 1 \\[2.0ex] \ThisIsLastRow
84 & 56 & 35 & 20 & 10 & 4 & 1 \\
\end{array}$
\end{document}
решение2
Учитывая желаемый вами результат, я думаю, я бы использовалmatrix of nodes
Полный код
% arara: pdflatex
% !arara: indent: {overwrite: true}
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[thick]
\matrix (mylattice)[
matrix of nodes,
row sep=.5cm,
column sep=.5cm,
nodes in empty cells,
execute at empty cell={\node[draw=none]{\phantom{X}};},
]{
& & & & & & & &\\
& 1 & 1 & 1 & 1 & 1 & 1 & 1 & \\
& 7 & 6 & 5 & 4 & 3 & 2 & 1 & \\
& 28 & 21 & 15 & 10 & 6 & 3 & 1 & \\
& 84 & 56 & 35 & 20 & 10 & 4 & 1 & \\
& & & & & & & & \\
};
\foreach \i [evaluate=\i as \y using int(\i+1)] in {1,...,5}
{
\foreach \j [evaluate=\j as \x using int(\j+1)]in {1,...,8}
{
\ifnum\j>1
\draw[red] (mylattice-\i-\j)--(mylattice-\y-\j);
\fi
\ifnum\i>1
\draw[blue] (mylattice-\i-\j)--(mylattice-\i-\x);
\fi
}
}
\end{tikzpicture}
\end{document}
Если, следуя комментариям, вам не нужны внешние части, вы можете использовать следующий слегка измененный код.
% arara: pdflatex
% !arara: indent: {overwrite: true}
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[thick]
\matrix (mylattice)[
matrix of nodes,
row sep=.5cm,
column sep=.5cm,
nodes in empty cells,
execute at empty cell={\node[draw=none]{\phantom{X}};},
]{
1 & 1 & 1 & 1 & 1 & 1 & 1 \\
7 & 6 & 5 & 4 & 3 & 2 & 1 \\
28 & 21 & 15 & 10 & 6 & 3 & 1 \\
84 & 56 & 35 & 20 & 10 & 4 & 1 \\
};
\foreach \i [evaluate=\i as \y using int(\i+1)] in {1,...,4}
{
\foreach \j [evaluate=\j as \x using int(\j+1)]in {1,...,7}
{
\ifnum\i<4
\draw[red] (mylattice-\i-\j)--(mylattice-\y-\j);
\fi
\ifnum\j<7
\draw[blue] (mylattice-\i-\j)--(mylattice-\i-\x);
\fi
}
}
\end{tikzpicture}
\end{document}