Algorithm 2D矩阵,找到两个数字之间直线路径上的所有数字
如果给定一个任意大小的二维正方形矩阵,如何在两个选定数字之间的路径上查找所有数字。e、 g:Algorithm 2D矩阵,找到两个数字之间直线路径上的所有数字,algorithm,Algorithm,如果给定一个任意大小的二维正方形矩阵,如何在两个选定数字之间的路径上查找所有数字。e、 g: | 1 | 2 | 3 | 4 | |----+----+----+----| | 5 | 6 | 7 | 8 | |----+----+----+----| | 9 | 10 | 11 | 12 | |----+----+----+----| | 13 | 14 | 15 | 16 | 对于6,16={11} 对于3,15={
| 1 | 2 | 3 | 4 |
|----+----+----+----|
| 5 | 6 | 7 | 8 |
|----+----+----+----|
| 9 | 10 | 11 | 12 |
|----+----+----+----|
| 13 | 14 | 15 | 16 |
对于6,16={11}
对于3,15={7,11}
对于9,2={}
对于4,13={7,10}
对于8,10={}
对于12,9={11,10}
等
首先,让我们构建一个函数来查找任意数字在nxn矩阵中的位置: 然后,给定2个数字a和b,取位置a=ax,ay和位置b=bx,通过 如果它们在同一行中,ax-bx=0。 如果它们在同一列中,则ay-by=0。 如果它们彼此成对角线,则absax-bx=absay-by。 只需评估条件并按正确顺序打印元素:
#include <bits/stdc++.h>
using namespace std;
int m[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int main(){
int n = 4;
while(true){
int a, b;
cin>>a>>b; //input elements
int ax = (a - 1) % n, ay = (a - 1) / n;
int bx = (b - 1) % n, by = (b - 1) / n;
pair<int, int> p;
int dx = bx - ax;
int dy = by - ay;
if(dx == 0 || dy == 0 || abs(dx) == abs(dy))
p = make_pair(dx < 0? -1 : dx > 0, dy < 0? -1 : dy > 0);
else continue; //there isnt a path in this case
while(true){
ax += p.first; ay += p.second;
if(ax != bx || ay != by) cout<<m[ay][ax]<<endl;
else break;
}
}
}
复杂性:启用,因为最多可以打印n个元素。首先,让我们构建一个函数,以查找n x n矩阵中任意数字的位置: 然后,给定2个数字a和b,取位置a=ax,ay和位置b=bx,通过 如果它们在同一行中,ax-bx=0。 如果它们在同一列中,则ay-by=0。 如果它们彼此成对角线,则absax-bx=absay-by。 只需评估条件并按正确顺序打印元素:
#include <bits/stdc++.h>
using namespace std;
int m[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int main(){
int n = 4;
while(true){
int a, b;
cin>>a>>b; //input elements
int ax = (a - 1) % n, ay = (a - 1) / n;
int bx = (b - 1) % n, by = (b - 1) / n;
pair<int, int> p;
int dx = bx - ax;
int dy = by - ay;
if(dx == 0 || dy == 0 || abs(dx) == abs(dy))
p = make_pair(dx < 0? -1 : dx > 0, dy < 0? -1 : dy > 0);
else continue; //there isnt a path in this case
while(true){
ax += p.first; ay += p.second;
if(ax != bx || ay != by) cout<<m[ay][ax]<<endl;
else break;
}
}
}
复杂性:启用,因为最多可以打印n个元素。在X/Y坐标中工作,如果需要,可以使用整数除法和moudulo从值计算它们
通过水平和垂直计算差异的最大公约数
int gcd (int a, int b) {
if (b == 0)
return a;
else
return gcd (b, a % b);
}
dx = abs(x2 - x1);
dy = abs(y2 - y1);
gc = gcd(dx, dy);
内部整数点的数量为n=gc-1,因此可以进行简单循环
xstep = (x2 - x1) / gc;
ystep = (y2 - y1) / gc; //both are integer values
for (i = 1; i < gc; i++) {
x = x1 + xstep * i;
y = y1 + ystep * i;
}
在X/Y坐标中工作,如果需要,可以使用整数除法和moudulo从值计算它们
通过水平和垂直计算差异的最大公约数
int gcd (int a, int b) {
if (b == 0)
return a;
else
return gcd (b, a % b);
}
dx = abs(x2 - x1);
dy = abs(y2 - y1);
gc = gcd(dx, dy);
内部整数点的数量为n=gc-1,因此可以进行简单循环
xstep = (x2 - x1) / gc;
ystep = (y2 - y1) / gc; //both are integer values
for (i = 1; i < gc; i++) {
x = x1 + xstep * i;
y = y1 + ystep * i;
}
编辑:我做了一个简化的假设,即您只想单步移动到紧邻的单元格。在本例中,您只查看水平、垂直或对角45度路径。然而,随着网格变大,可以考虑通过跨越相邻单元的细胞中心的直线路径。例如,在尺寸为7的网格上,10和19介于1和28之间——MBo在其评论中提供的示例。要处理这些情况,你需要在确定步长时加入最大公约数,正如MBo在他的报告中所概述的那样
只需计算从第一个单元格到第二个单元格的位置和步长的行和列差异
下面是一些Java代码来说明:
static int[] gridCells(int size, int from, int to)
{
int fromRow = (from-1) / size;
int fromCol = (from-1) % size;
int toRow = (to-1) / size;
int toCol = (to-1) % size;
int rowDiff = toRow - fromRow;
int colDiff = toCol - fromCol;
if(rowDiff == 0 || colDiff == 0 || Math.abs(rowDiff) == Math.abs(colDiff))
{
int maxStep = Math.max(Math.abs(rowDiff), Math.abs(colDiff));
if(maxStep > 1)
{
int rowStep = rowDiff / maxStep;
int colStep = colDiff / maxStep;
int[] cells = new int[maxStep-1];
for(int i=0; i<cells.length; i++)
cells[i] = (fromRow + (i+1)*rowStep) * size + fromCol + ((i+1)*colStep) + 1;
return cells;
}
}
return new int[]{};
}
输出:
[5, 5] : []
[6, 16] : [11]
[3, 15] : [7, 11]
[9, 2] : []
[4, 13] : [7, 10]
[8, 10] : []
[12, 9] : [11, 10]
编辑:我做了一个简化的假设,即您只想单步移动到紧邻的单元格。在本例中,您只查看水平、垂直或对角45度路径。然而,随着网格变大,可以考虑通过跨越相邻单元的细胞中心的直线路径。例如,在尺寸为7的网格上,10和19介于1和28之间——MBo在其评论中提供的示例。要处理这些情况,你需要在确定步长时加入最大公约数,正如MBo在他的报告中所概述的那样
只需计算从第一个单元格到第二个单元格的位置和步长的行和列差异
下面是一些Java代码来说明:
static int[] gridCells(int size, int from, int to)
{
int fromRow = (from-1) / size;
int fromCol = (from-1) % size;
int toRow = (to-1) / size;
int toCol = (to-1) % size;
int rowDiff = toRow - fromRow;
int colDiff = toCol - fromCol;
if(rowDiff == 0 || colDiff == 0 || Math.abs(rowDiff) == Math.abs(colDiff))
{
int maxStep = Math.max(Math.abs(rowDiff), Math.abs(colDiff));
if(maxStep > 1)
{
int rowStep = rowDiff / maxStep;
int colStep = colDiff / maxStep;
int[] cells = new int[maxStep-1];
for(int i=0; i<cells.length; i++)
cells[i] = (fromRow + (i+1)*rowStep) * size + fromCol + ((i+1)*colStep) + 1;
return cells;
}
}
return new int[]{};
}
输出:
[5, 5] : []
[6, 16] : [11]
[3, 15] : [7, 11]
[9, 2] : []
[4, 13] : [7, 10]
[8, 10] : []
[12, 9] : [11, 10]
数字一定是1,2,3?如果是的话,就不需要地图了。数字一定是1,2,3?如果是这样的话,就不需要地图了。遗憾的是,只对水平、垂直和45度路径给出了正确的结果,最后一对路径预期为{18}和{10,19}。遗憾的是,只对水平、垂直和45度路径给出了正确的结果,最后一对路径预期为{18}和{10,19}