我试图解决的问题是这样的。
我已经N
,告诉我数字的范围是0
,1
,...
,N-2
,{{1} }。
我也给了配对,告诉我这些数字对在同一个"组"。
前:
N-1
,N=6
和0
已配对,1
和1
已配对,4
和2
为配对,我知道其余的数字都在他们自己的组中。
然后我知道分组是3
,{0, 1, 4}
,{2, 3}
。
在这些群组中从不同群组中选择两个号码的方式的数量是{5}
,这是我尝试解决的数字。这些选择是:
11
,
{0,2}
,
{0,3}
,
{0,5}
,
{1,2}
,
{1,3}
,
{1,5}
,
{4,2}
,
{4,3}
,
{4,5}
,
{2,5}
有人可以帮助弄清楚我的逻辑错在哪里吗?因为我没有通过更大的测试用例并传递较小的测试用例。
我的代码:
{3,5}
例如,我正在传递
static int Combinations(int N, int K)
{
decimal result = 1;
for (int i = 1; i <= K; i++)
{
result *= N - (K - i);
result /= i;
}
return (int)result;
}
/// <summary>
/// Given a set of n numbers 0, 1, ..., n-1 and a list of pairs
/// of the numbers from the set where each pair (i,j) means that
/// number i and j are in the same group, find the number of ways
/// to choose 2 numbers that are not in the same group.
/// </summary>
static int PoliticallyCorrectPairs(int n, Tuple<int, int>[] pairs)
{
// Create a map that from each number to a number representing
// the group that it is in. For example, if n = 5 and
// pairs = { (0, 1), (2, 3), (0, 4) }, then the map will look
// like
// 0 -> 1
// 1 -> 1
// 2 -> 2
// 3 -> 2
// 4 -> 1
// indicating that 0,1,4 belong to one group and 2,3 to the other.
int[] gmap = new int[n];
int k = 1;
foreach(Tuple<int, int> pair in pairs)
{
int i = pair.Item1,
j = pair.Item2;
// If both i and j are already in groups, combine those into a
// single group if it isn't already.
if (gmap[i] != 0 && gmap[j] != 0)
{
if(gmap[i] != gmap[j])
{
for(int m = 0; m < n; ++m)
if(gmap[m] == gmap[j])
gmap[m] = gmap[i];
}
}
else if(gmap[j] != 0) // j is in a group and i isn't
gmap[i] = gmap[j]; // add i to j's group
else if(gmap[i] != 0) // i is in a group and j isn't
gmap[j] = gmap[i]; // add j to i's group
else
gmap[i] = gmap[j] = k++; // Put both in same new group.
}
// Those not assigned to a group each end up in a group alone.
for(int i = 0; i < gmap.Length; ++i)
if(gmap[i] == 0)
gmap[i] = k++;
// Get the group sizes as an array.
int[] gcnts = gmap.GroupBy(x => x).Select(g => g.Count()).ToArray();
// Total number of ways to choose pairs of numbers.
int totalCombinations = Combinations(n, 2);
// Number of pairs from previous count that are in the same group.
int impossibleCombinations = gmap.GroupBy(x => x)
.Select(g => g.Count())
.Where(count => count > 1)
.Sum(count => Combinations(count, 2));
return totalCombinations - impossibleCombinations;
}
但失败
[TestMethod]
public void Sample1()
{
int N = 5;
Tuple<int, int>[] pairs = new Tuple<int, int>[]
{
Tuple.Create(0, 1),
Tuple.Create(2, 3),
Tuple.Create(0, 4)
};
Assert.AreEqual(6, PoliticallyCorrectPairs(N, pairs));
}
知道我哪里出错了吗?
答案 0 :(得分:2)
问题出在结合部分:
if(gmap[i] != gmap[j])
{
for(int m = 0; m < n; ++m)
if(gmap[m] == gmap[j]) // here
gmap[m] = gmap[i];
}
当m
点击j
时,gmap[j]
会被gmap[i]
替换,因此会根据gmap[i]
检查其余元素。
只需将替换后的值放入局部变量:
if(gmap[i] != gmap[j])
{
int g = gmap[j];
for(int m = 0; m < n; ++m)
if(gmap[m] == g)
gmap[m] = gmap[i];
}