C# 矩阵左上象限的最大和,可通过行和列反转形成

C# 矩阵左上象限的最大和,可通过行和列反转形成,c#,algorithm,data-structures,time-complexity,C#,Algorithm,Data Structures,Time Complexity,我正在研究一个HackerRank问题,它是在一个2nx2n矩阵的左上象限中,在颠倒行和列之后,求元素的最大和。例如,如果矩阵是 M = [ 112 42 83 119 56 125 56 49 15 78 101 43 62 98 114 108 ]; 那么,在得到矩阵后,可以通过颠倒行和列来形成的最大和是119+114+56+125=414 M' = [ 119 114 42 112 56 125 101

我正在研究一个HackerRank问题,它是在一个2nx2n矩阵的左上象限中,在颠倒行和列之后,求元素的最大和。例如,如果矩阵是

M = [
  112  42   83   119
  56   125  56   49
  15   78   101  43
  62   98   114  108
];
那么,在得到矩阵后,可以通过颠倒行和列来形成的最大和是
119+114+56+125=414

M' = [
   119  114  42   112
   56   125  101  49
   15   78   56   43
   62   98   83   108
];
从第2列到第0行

我没有想出一个简单的解决办法,但我提出了一些可能有用的事实:

  • 不可能通过反转行和列来获得任何配置。因此,答案不可能是简单地对所有元素进行排序,然后将它们中的前
    NxN
    相加
  • 此外,不可能将任何1个元素移动到任何其他位置。例如,(N-1,N-1)处的元素可能要移动的唯一位置是(0,N-1),(N-1,0),(0,0)
  • 从右上象限或左下象限到左上象限需要1行反转,从右下象限到左上象限需要2行反转
  • 不可能找到一个简单地查看左上象限中的每个元素并检查它是否可以替换为可以在其位置移动的元素范围内的较大元素的解决方案(例如,
    M[0,1]=42
    可以替换为
    M[0,2]=83
    M[3,2]=114
    M[3,1]=98
    )因为您还必须考虑进程中拖动的其他元素。<李>

除了这些事实,我想不出任何东西可以帮助我构建一个简单的解决方案。有没有明显的事实证明我失踪了?昨晚我熬夜思考这件事

让我们来观察以下事实:元素
(N-1,N-1)
只能位于
(0,0)
(N-1,0)
(0,N-1)
位置

  • 考虑一个
    (r,c)
    元素。人们可以观察到它只能处于以下四个位置之一:
    (r,c)、(N-r-1,c)、(r,N-c-1)
    (N-1-r,N-1-c)

  • 可以看出,始终存在一系列操作,这些操作将位于上述矩形顶点的四个数字中最大的一个放在左上象限,而不改变其余部分(为了证明这一点,我们可以考虑所有的情况,并提供一个明确的结构来完成它。这是很长但很简单的,所以我不会在这里张贴)。< /P> <
  • 这两个观察结果给出了以下解决方案:

    int sum = 0;
    for (int i = 0; i < n / 2; i++)
        for (int j = 0; j < n / 2; j++)
            sum += max(a[i][j], a[i][n - j - 1], a[n - i - 1][j], a[n - i - 1][n - j - 1]); 
    
    int和=0;
    对于(int i=0;i

在没有想到快捷方式的情况下,始终可以进行委托。不仅可以委托给stackoverflow用户,还可以委托给CPU。即暴力搜索。 暴力适用于这个小矩阵-给定深度4已经足够了,并且给定树的分支因子是
(2*N)
,其中N分别是行数和列数。(N行可以反转,N列可以反转。)

这里,对于问题中的4x4矩阵,相应的解决方案如下:

int sum = 0;
for (int i = 0; i < n / 2; i++)
    for (int j = 0; j < n / 2; j++)
        sum += max(a[i][j], a[i][n - j - 1], a[n - i - 1][j], a[n - i - 1][n - j - 1]); 
let数据=
设值=
[|
112;  42 ;  83;   119;
56 ;  125;  56;   49;
15 ;  78 ;  101;  43;
62 ;  98 ;  114;  108
|]
Array2D.init 4(有趣的rc->values.[4*r+c])
设上象限和(m:int[,])=
[对于0..1中的r,对于0..1中的c,do屈服(r,c)]
|>List.sumBy(fun(r,c)->m[r,c])
让我们来看看下面的行(m:int[,])=
Array2D.init 4 4(乐趣rc->如果r=row,那么m[r,3-c]否则m[r,c])
设reverseCol列(m:int[,])=
Array2D.init 4 4(fun r c->如果c=col,那么m[3-r,c]否则m[r,c])
让可能的反应=
[reverseRow 0;reverseRow 1;reverseRow 2;reverseRow 3;
reverseCol 0;reverseCol 1;reverseCol 2;reverseCol 3;
]
让我们最大化度量maxDepth m0=
让rec搜索深度m=
设值=公制m
如果深度=最大深度
然后价值
其他的
可能的反应
|>List.map(乐趣a->让m1=a最大值为m(公制m1)(搜索(深度+1)m1))
|>List.max
|>乐趣msearch->max value msearch
搜索0 m0
让solve=最大化上象限和
在fsi中,发布:

解算7个数据;;
val it:int=414

当然,如另一个答案所述,一旦想到优化, 使用蛮力解决方案来验证两者是否都能产生 同样的结果:

让内联解算器1 m=
设n=阵列2d.长度1 m
让候选人r c=
[r,c;n-1-r,c;r,n-1-c;n-1-r,n-1-c]
[
对于0..n/2-1 do中的r
对于0..n/2-1 do中的c
收益率(候选项rc |>List.map(fun(r,c)->m[r,c])|>List.max)
]|>List.sum
解算1数据

很抱歉没有用C#编写代码,但是一个.fsx文件和fsi比创建另一个C#应用程序要简单得多…

你能提供一个指向原始问题的链接(到约束和内容)吗?@kraskevich我想我描述得很好,但是如果你需要。。。