SRM 148 Division-I, Level 2

Problem Statement
   
9 numbers need to be arranged in a magic number square. A magic number square is a square of numbers that is arranged such that every row and column has the same sum. For example:
1 2 3
3 2 1
2 2 2
Create a class MNS containing a method combos which takes as an argument a vector <int> numbers and returns the number of distinct ways those numbers can be arranged in a magic number square. Two magic number squares are distinct if they differ in value at one or more positions. For example, there is only one magic number square that can be made of 9 instances of the same number.
Definition
   
Class:
MNS
Method:
combos
Parameters:
vector <int>
Returns:
int
Method signature:
int combos(vector <int> numbers)
(be sure your method is public)
   

Notes
-
Unlike some versions of the magic number square, the numbers do not have to be unique.
Constraints
-
numbers will contain exactly 9 elements.
-
each element of numbers will be between 0 and 9, inclusive.
Examples
0)

   
{1,2,3,3,2,1,2,2,2}
Returns: 18

1)

   
{4,4,4,4,4,4,4,4,4}
Returns: 1

2)

   
{1,5,1,2,5,6,2,3,2}
Returns: 36

3)

   
{1,2,6,6,6,4,2,6,4}
Returns: 0

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

Given the numbers, simply try all permutations and check each to see if it is valid. Validity amounts to checking whether the row sums and column sums are equivalent. To remove duplicates you can either use a set data structure that will check automatically, or you can divide out to remove potential duplicates. For example, if the number 3 occurred 4 times, dividing by 4! removes all duplicates associated with swapped 3's. To actually generate the permutations, a recursive algorithm that tries each order does the trick. C++ coders can use the built in next_permutation function for a similar effect. As an alternate method, Java users can implement an iterative next permutation function much like the one found in the C++ library. Such an implementation follows:

//Members of vals must be distinct
//Based on C++ next_permutation function
int[] nextperm(int[] vals) {
int i = vals.length-1;
while (true) {
int ii = i;
i--;
if (vals[i] < vals[ii]) {
int j = vals.length;
while (vals[i] >= vals[--j]);
int temp = vals[i]; //Swap
vals[i] = vals[j];
vals[j] = temp;
int begin = ii, end = vals.length-1;
while (end>begin) {
int stemp = vals[end]; //Swap
vals[end] = vals[begin];
vals[begin] = stemp;
end--; begin++;
}
return vals;
}
else if (vals[i] == vals[0]) {
int begin = 0, end = vals.length-1;
while (end>begin) {
int stemp = vals[end]; //Swap
vals[end] = vals[begin];
vals[begin] = stemp;
end--; begin++;
}

return vals;
}

}
}
Since nextperm only works on lists of numbers without duplicates we will use a sort of hack to get it to work. Generate an array containing the numbers 0-8. Permute that array to get all permutations. Use the permuted list of numbers at any one point as the ordering to impose on the actual list that may contain duplicates.

Code

你可能感兴趣的:(visio)