Блог пользователя SummerSky

Автор SummerSky, история, 8 лет назад, По-английски

A. You're Given a String...

The problem asks to find out such a substring that has the longest length and occurs at least two times, which is in fact equivalent to looking for two substrings (they might overlap with each other) with the longest length while they are exactly the same with each other. The solution might be simplified if one has noticed that the string consists of lower-case Lattin letters merely, i.e., a,b,...,z. The idea behind the simplification is that if two substrings are exactly the same, then their first letters must be the same as well. Thus, we can first use 26 arrays to store the positions at which each letter appears. For instance, we can assign 26 vectors (in C++ STL) for each letter, and "puch_back" the corresponding index. This can be done by traversing the string for a single time, with complexity O(N) (we use N to denote the length of string).

For each vector, we enumerate all the feasible combination of two indices (or positions), and start with these two positions and check their next one single letter at the same time. It is obvious that we will obtain two substrings and as we should keep them exactly the same, we must stop if the next one single letter of each substring is different. For instance, suppose that letter "a" has positions {1,5,7}. Then, we should check {1,5}, {1,7} and {5,7}. We adopt {1,7} as an example, i.e., we should check whether the two substrings {s[1],s[2]} and {s[7],s[8]} are the same or not. If they are the same, then we move on to check {s[1],s[2],s[3]} and {s[7],s[8],s[9]}; otherwise, we stop and store the current length. Finally, we output the maximum length as the answer.

Now, we calculate the complexity of the above solution. We denote the length of the 26 vectors as x1,x2,...,x26. For each vector, we should check xi*(xi-1)/2 combinations. For each combination, we will check at most 2N letters. Thus, the total complexity is {x1*(x1-1)/2+x2*(x2-1)/2+...+x26*(x26-1)/2}*2*N=O(N^3).

B. Party

Well, this problem is somewhat marvellous...

We first prove that the answer cannot be n. Note that each person can only have friends with number of 0,1,...,n-1. Therefore, when we count from 0 to n-1, some of them must leave.

Next, we prove that the answer cannot be n-1. Suppose that the person leaves when we count at x. This means that for the "stayed" n-1 people, the number of friends is reduced by one for x of them while nothing changes for the other n-1-x people. Due to similar reasons at the first case, the n-1-x people cannot all stay at the party, which is contradictory to our initial assumption. However, this can be true if and only if n-1-x=0, which gives x=n-1, i.e., the single person leaves when we count at n-1. This implies that the other n-1 people all have friends with number of n-1, since none of them leaves when we count from 0 to n-2. Nevertheless, this also means that when we count at n-1, all the n people will leave, which is contraditory to the initial assumption again.

Thirdly, we prove that the answer is n-2. Actually, the above two cases may have inspired us a little. Note that when some people leave when we count at x, the number of friends may be reduced by one for some of the "stayed" people, and it is just these people that have chances to survive until the end while for the other "unchanged" (number of their friends) people, they cannot all survive due to similar reasons at the first case. The reason is that: the "changed" people might have friends no more than x after some people leave, and as we count from x+1 to n-1, they will never leave. In a word, we should find out the minimum number of people that are "sacrificed" to protect the other people to survive till the end.

Here is one feasible construction. We let the two persons have friends with number of n-2 while the other n-2 people have friends with number of n-1. Then, when we count from 0 to n-3, all people stay at the party while when counting at n-2, the two persons leave and the currently "stayed" n-2 people have friends with number of n-1-1. When we count at n-1, the previously "survived" people continue to survive.

Finally, my question is: how could the first person come up with such a solution....I think it is more difficult to analyze this problem without any prior knowledge than to figure out the reasons and logics if I have been told that the answer is n-2. The above solution seems to be some "exclusive" method, but how to realize that I should try from n,n-1,n-2 other than 0,1,...

C. Oranges and Apples

I think this is a delicately designed problem! At first we introduce some preliminaries. Suppose that there is a sequence x[1],x[2],...,x[2*N-1], which is sorted in a decreasing order, i.e., x[1]>x[2]>x[3]>...x[2*N-2]>x[2*N-1] (the following derivation still holds if replacing any ">" with ">="). Then, we have the following two results:

1) First rewrite x[1]>x[2]>x[3]>...x[2*N-2]>x[2*N-1] as x[1]>x[2],x[3]>x[4],x[5]>x[6],...,x[2*N-3]>x[2*N-2],x[2*N-1]>0. Then, add the terms on the left hand side and right hand side, respectively, which gives x[1]+x[3]+x[5]+...+x[2*N-1]>x[2]+x[4]+x[6]+...+x[2*N-2]. Suppose that the total sum is S=x[1]+x[2]+x[3]+...+x[2*N-2]+x[2*N-1]. It can then be seen that x[1]+x[3]+x[5]+...+x[2*N-1]>S-(x[1]+x[3]+x[5]+...+x[2*N-1]), which is equivalent to x[1]+x[3]+x[5]+...+x[2*N-1]>S/2.

2) Rewrite x[1]>x[2]>x[3]>...x[2*N-2]>x[2*N-1] as x[1]>0,x[2]>x[3],x[4]>x[5],...,x[2*N-2]>x[2*N-1]. Then, add the terms on the left hand side and right hand side, respectively, and we obtain x[1]+x[2]+x[4]+...+x[2*N-2]>x[3]+x[5]+x[7]+...+x[2*N-1]. Recall that S=x[1]+x[2]+x[3]+...+x[2*N-2]+x[2*N-1], which implies that x[1]+x[2]+x[4]+...+x[2*N-2]>S-(x[1]+x[2]+x[4]+...+x[2*N-2]), i.e., x[1]+x[2]+x[4]+...+x[2*N-2]>S/2.

It can also be observed that: for case 1), we have (2*N-1+1)/2=N terms, i.e., x[1],x[3],x[5],...,x[2*N-1], of which the sum is not less than half of the total sum; for case 2), we also have 1+(2*N-2)/2=N terms, i.e., x[1],x[2],x[4],...,x[2*N-2], satisfying the condition that their sum is not less than half of the total sum.

Based on the above results, we can sort the boxes in a decreasing order of the number of apples (or oranges), and then calculate two sums: S1=o[1]+o[3]+o[5]+...+o[2*N-1] (if the boxes are sorted based on oranges, then we compute S1=a[1]+a[3]+a[5]+...+a[2*N-1] instead) and S2=o[1]+o[2]+o[4]+...+o[2*N-2] (if the boxes are sorted based on oranges, then we compute S2=a[1]+a[2]+a[4]+...+a[2*N-2] instead). Now, if S1>=S2, then we select those boxes with indices 1,3,5,...,2*N-1; otherwise select those ones with indices 1,2,4,6,...,2*N-2. The reason is that: for S1>=S2, the number of oranges satisfy the request since S1>=S-S1, i.e., S1>=S/2, while the number of apples can meet the request as well according to case 1); for S1<S2, it can be seen that both the number of oranges and apples is not less than half of each total sum, according to S2>S/2 and case 2), respectively.

The above arguments in fact demonstrate that the answer will always te YES.

  • Проголосовать: нравится
  • -5
  • Проголосовать: не нравится

»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by SummerSky (previous revision, new revision, compare).