我偶然发现了这个算法问题,我无法获得比蛮力更好的方法,有人可以指导我吗?
给定M * N字符网格(A,B)。你可以翻转任何一个 列数,即将A更改为B,将B更改为A.最大值是多少 在所有可能的翻转之后可以具有相同符号的行数
例如,
A B A|
B A B|
A B B|
B B A|
答案是2,如果我们翻转第1列和第1列如果需要进一步说明,请告诉我。
答案 0 :(得分:1)
我有一个O(n^2)
和O(M)
解决方案但是比bruteforce好一点,因为第二个循环开始到第一个循环的i+1
,请告诉我你对它的看法: / p>
首先,我们需要更改位矩阵的A,B矩阵,其中每一行都是矩阵成为的二进制:
0 1 0|
1 0 1|
0 1 1|
1 1 0|
现在这是基于按位" 010& 101 = 000"因此,如果存在可能使行匹配的列排列。
Given N and M;
int maxSameSymbole[M] = {0};
for (int i = 0; i < M; i++) {
for (int j = i+1; j < M; j++) {
if (!(line[i].toBinary & line[j].toBinary)) //this will equal 0 if there is a possible flip that will make the 2 rows with the same symbole
maxSameSymbole[i]++;
}
}
// Simple find max in the maxSameSymbole list :
int max = maxSameSymbole[0];
for (int i = 0; i < M; i++) {
if (maxSameSymbole[i] > max)
max = maxSameSymbole[i];
}
希望这有助于找到更好的解决方案。
答案 1 :(得分:1)
从第一列开始,如果翻转该列,则获取具有相同符号的行的索引。例如:(1,4,9)行工作。为每个列获取这些索引,并将它们作为键映射到映射列表中的键,并将索引列表映射到它出现的数字。最高的价值就是答案。
答案 2 :(得分:1)
首先请注意,A B A
和B A B
对于此问题的目的基本相同:每当有人翻转到所有A
时,另一个被翻转到所有B
1}} s,反之亦然,所以两者同时计算答案。
另一方面,当翻转A B A
或B A B
以使其包含相同的字母时,所有其他可能的行都包含不同的字母。
因此,第一个建议的步骤是翻转以B
开头的所有行,因为它将合并同时计算答案的行对。
现在,我们有
A B A|
A B A| (flipped from B A B)
A B B|
A A B| (flipped from B B A)
剩下的是找到最常出现的行。
这可以通过构建一个映射来完成,该映射将行映射到它们出现的次数。
例如,它看起来像{A B A
:2,A B B
:1,A A B
:1}`。
现在,A B A
显然赢了,因为它出现了两次,所以我们在该行中翻转了B
个所有列。使用A
翻转所有列是另一种选择。