P3087 [USACO13NOV] Farmer John Has No Large Brown Cow S Solution
The content below was generated entirely by machine translation. Please verify its accuracy. If anything is unclear, consult the Chinese source version.
The reading experience is better on the blog
Preface: This solution may be rather verbose, mainly because I wrote down my entire thought process. Therefore, if you already have the basic idea, or if you are looking for a concise solution, you can skip this solution.
1: Understanding the Problem
There are cows and classes of adjectives. There are adjectives in the th class, and the th adjective in the th class is . Every cow must be modified, in order, by one adjective from each of these classes. You are told to remove of the cows. Among the remaining cows, after sorting them in lexicographic order, which cow is in position ?
2: Analysis and Problem Transformation
2.1: The Connection with Number Systems
This description alone may be somewhat abstract. Let us first look at the sample, then think about how to solve the problem on the basis of that sample.
In the sample, and . The values of are as follows:
| (first adjective class) | “large” | “small” | N/A |
| (second adjective class) | “brown” | “white” | “spotted” |
| (third adjective class) | “noisy” | “silent” | N/A |
Because the sample asks for the seventh cow in lexicographic order, we can first consider what the process of sorting by lexicographic order looks like.
For example, suppose the two strings “abc” and “cde” must be sorted lexicographically. We first compare the lexicographic order of the first characters, “a” and “c”; then compare the second characters, “b” and “d”; and only finally compare the third characters.
From this process, we can see that each character position has a different influence on the lexicographic order of the whole string. The first position has the greatest influence, and the last position has the least. We can therefore say that they have different “weights” in determining the lexicographic order of the complete string. If different strings are sorted from small to large lexicographically, then for any string, no matter how small the characters from the second position through the last position are, a very large first character will still place the string late in the ordering.
Looking again at the problem we need to solve, we can see that an adjective from the first class, such as “large”, has the greatest influence on the whole sequence of characters. An adjective from the second class, such as “brown”, has the next greatest influence, and the third class comes last.
At this point, I believe you can already sense the connection between this problem and a number system.
That connection is that, when comparing numbers, we also compare them from the highest digit to the lowest digit.
For example, consider the decimal number .
The digit represents the value , the largest value represented by any digit here ( is in the first position).
The digit represents , the second-largest represented value ( is in the second position).
A digit in position represents , and the value represented by the complete decimal number is the sum of the values represented by all its digits.
Generalizing this rule to base , a digit in position represents .
2.2: Solving a Simplified Problem
Here is the problem: whether we use the decimal system discussed above or a base- system, the mechanism is always “carry 1 upon reaching .” Consequently, the value represented by the digit 1 in position is necessarily times the value represented by the digit 1 in position . In this problem, however, the number of adjectives in each class is not necessarily the same.
We can first try to solve the case where every adjective class contains a fixed number of adjectives. Suppose every class contains adjectives. We first sort the adjectives in each class lexicographically and store the result in rank[i][j], where denotes the adjective class and denotes the rank.
The purpose of this step is to convert strings into numbers, making later calculations easier. We map every adjective to “digit in position ” of the number system. One point needs attention, however: the smaller the adjective-class number, the greater its influence on the overall lexicographic order, whereas the smaller the digit position in an ordinary number, the smaller its influence on the number’s total value.
Because we have completed the mapping from adjectives to numbers, the next task is equivalent to converting a decimal number to base , then converting the resulting digits back into the corresponding strings.
This may still sound abstract, so let us simulate the process.
Suppose the first adjective class is {"a","b"}, the second is {"c","d"}, and the third is {"e","f"}.
We can then obtain the following rank array. The ranks start from 0 to make calculation convenient.
| (first adjective class) | “a” | “b” |
| (second adjective class) | “c” | “d” |
| (third adjective class) | “e” | “f” |
If we want the cow in the third lexicographic position, we first find the binary representation of 3, namely . We then reverse the number to obtain . This reversal is necessary because a smaller adjective-class number has a greater influence on the overall lexicographic order, while a smaller digit position has a smaller influence on a number’s total value. Finally, map back to the corresponding strings, with each position corresponding to its respective class. The final answer is “a, d, f”.
2.3: Solving the Original Problem
While solving the simplified problem, we mapped each adjective class to a digit position in the number system, mapped its rank to digit , and made the number of adjectives in each class the base of the number system.
We can see that the key to the original problem is the base. In the simplified problem, every digit position in the number system had the same base, and every adjective class contained a fixed number of adjectives. In the actual problem, the number of adjectives differs among classes, so the base must also change from one digit position to another.
Return to the sample. The numbers of adjectives in the respective classes are , , and .
We mapped the third adjective class to the first digit of the number system, the second class to the second digit, and similarly the first class to the third digit.
We can therefore specify that the number system is binary in its first digit, ternary in its second digit, and binary again in its third digit.
Although this mixed base of “” can describe every possible cow, solving the problem also requires converting a decimal number into this mixed-radix representation.
Everyone is surely familiar with converting decimal to binary. For example, to convert a decimal number into an -digit binary number , start with the highest digit of . At each step, calculate , then calculate .
Written as a program, it looks like this:
1 | // k is the decimal number. |
Thus, for a mixed radix such as “”, we need only precompute the decimal value represented by every digit position, after which we can convert a decimal number into that mixed radix.
The decimal value represented by a position means the decimal value obtained when that position is 1 and every other position is 0 in the original radix system.
How do we calculate the decimal value represented by each position in such a system?
In any radix system, as long as two numbers use the same radix system, the value represented by a number with more digits must be greater than the value represented by one with fewer digits.
We can therefore calculate the decimal value represented by position as the decimal value represented by position , multiplied by the largest digit that position can represent plus 1. This ensures that a number with more digits is always greater than one with fewer digits. We can also see that the largest digit plus 1 is exactly the base of that position; for example, the largest digit in binary is 1.
With this conclusion, we can recursively calculate the decimal value represented by every position. Store the result in weight_in_pos[i], which is the value represented by position , and initialize the value represented by the first position to 1.
In the sample’s “” radix system, the decimal value represented by the first position is initialized to 1. The weight_in_pos value for the second position is , and the value for the third position is .
At this point, we can calculate the cow in position among all possible cows. The problem, however, asks which cow is in position among the remaining cows after lexicographic sorting.
This small issue is relatively easy to solve. We can transform into a rank among all cows rather than a rank among only the remaining cows. First calculate the ranks, among all cows, of the cows that must be removed. If one of those cows has a rank less than or equal to , increment by 1. This is equivalent to saying that some of the first cows cannot be selected; because we still need to select cows, we must account for every removed cow whose rank is smaller than .
Code and Details
All details are explained in the comments.
1 |
|
That is the end of the solution. If you find a problem with it or encounter something you cannot understand, you are welcome to send me a private message or leave a comment. If you found it helpful, please give it a like. Thank you.






![[Stanford CS144] Lab 4 Record](/img/CS144/tcp%E7%8A%B6%E6%80%81%E6%B5%81%E8%BD%AC%E5%9B%BE.jpg)