NUS Home

Ok, finally AC for 10534. My mistake was that my condition for the wavio seq was length of LIS ending at i == length of LDS starting from i.
That is obviously wrong, as Junbin pointed out it should be min(length of LIS ending at i, length of LDS starting from i). As a reference the timing was 0.789s. Do practice this question to get experience in using the
O(nlgn) LIS algorithm.

Regards,
Melvin Zhang


On Sat, 10 Jul 2004, Teng Junbin wrote:

> Questions attempted: 10531 - 10538
> Questions solved:
> 10532
> 10533
> 10534
> 10536
> 10537
>
> Discussion:
>
> 10531:
> No one has any idea. :)
>
> 10532:
> DP/Brute force with memoization.
>
> First, convert the given list of numbers into an array of frequencies,
> so
> 1 1 2 3 4 4 4 5
> would be
> 2 1 1 3 1
>
> With this, define:
>
> Ways( a , b ) as the number of ways to select b items starting from
> index a of the transformed array.
>
> Answer is then Ways(0, r)
>
> Ways(x, r) = Sum of ( Ways( x+1, r - i ) where i range from 0 to total of
> array2[ x ] )
>
>
> 10533:
> Easiest way (though not fastest) is to use sieve to determine the primes.
>
> Then for each prime, determine if it's a digit prime and then define:
>
> Count[x] = number of digit primes BEFORE number x.
>
> Then answer is just Count[b] - Count[a]
>
>
> 10534:
> You need to use log n algorithm to find the LIS from the start and
> from the end.
> Then the longest wavio at each point is just MIN( LIS_from_front,
> LIS_from_back )
>
>
> 10535 :
> The idea is to arrange the end points of the walls in increasing angle
> then detemine the point where you encounter the most walls. This is
> very complicated and no one could solve it using this method.
>
> The other method we thought of after the training was to use
> bruteforce at every endpoint. This seems plausible, though no one did it yet.
>
>
> 10536:
> Same as Game of 31, just emulate the possibilities and use brute force
> with memoization
>
>
> 10537:
> Use Dijkstra's algorithm but start from the end, since this way, the
> cost of each link is deterministic.
>
> 10538:
> No one has any idea, though pre-compute seems plausible.
>
>
> junbin
>
>
 

First of all, let's welcome Zichao (I think your surname is Liew, correct me if I'm wrong). :)
 
Questions attempted: 10539 - 10543
 
Questions solved:
 
10539
10541
10543
 
 
10542 - Solved by Stephanus before hand
 
 
 
Discussion:
 
10539:
There are two methods to doing it. The faster method is to use sieve to generate the primes between 1 and 1000000, then find all multiples of these primes.  Sort the multiples and use binary search to get the answer.
 
The other method is to find the smallest prime, p, such that p^2 is smaller or equal to the end point.  Then use bruteforce to determine the answer.  (by Bang)
 
10540:
There is a recursive mathematical formula for it, but no one managed to work that out in time.
 
10541:
Very simple DP/brute force w/ memoization problem.  Slight note:  It is easier to code big integer using little endian (smallest value digit in front) then reverse before you print.
 
10542:
Mathematical formula again.  The formula can be found on the forum (by Stephanus)
 
10543:
If you listened in CS1231 (I'm sure you did :)  you'll realise this can be solved using matrix multiplication.  An improvement would be to reduce the matrix to two single dimension arrays.  One is the souce array, the other is the destination array.   Every turn, you use the source array to determine which positions you can end at after that turn and store the result in the destination array.  Then you flip the two arrays (source becomes destination and vice versa).
 
 
 
junbin
10680: I used the sieve as well.. though I used it only after I generated the primes.. maybe that's why.
 
10679: I'm not even sure my code was KMP... I read about KMP before and understood the idea behind it.. but I didn't read the code.. so I had to do it from scratch.. so my code could very well not be KMP :p but other then that, there's nothing special.
 
 
junbin
 
-----Original Message-----
From: Do Huy Hoang [mailto:u0302796@nus.edu.sg]
Sent: Sunday, 04 July, 2004 5:25 PM
To: Teng Junbin; Zhou Junyu; Cai Junfu; Daniel Chia; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sim, Yan Chuan; Sing Kiat Oh; Stephanus; Steven Halim; Viet Bang Nguyen; Wailun Tam; Wang Zirui; You Quan Chong
Subject: RE: Addon notes

 

Problem 10680: I used “The Sieve of Eratosthenes”. The code and time is much better.

 

Problem 10679: I also tried KMP, but it got TLE. They said that Aho-Corasick algorithm would work, but I think this algorithm use too much memory. L

To Junbin: Did you use special technique in your KMP?

 

Hoang

 


From: Teng Junbin [mailto:tengjb@singnet.com.sg]
Sent: Saturday, July 03, 2004 10:58 PM
To: Zhou Junyu; Cai Junfu; Daniel Chia; Guo Yunsong; Do Huy Hoang; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sim, Yan Chuan; Sing Kiat Oh; Stephanus; Steven Halim; Viet Bang Nguyen; Wailun Tam; Wang Zirui; You Quan Chong
Subject: Addon notes

 

10680:

Given

a = p1^c1 + p2^c2 + p3^c3 ... + pn^cn

b = p1^d1 + p2^d2 + p3^d3 ... + pn^dn

 

where the RHS is the prime factorization of the LHS,

 

then we know that LCM(a, b) = p1^MAX(c1, d1) + p2^MAX(c2, d2) + ... pn^MAX(cn, dn)

 

Also, LCM of a, b and c = LCM( LCM(a, b)  , c)

 

 

Therefore, given that x = LCM of 1 to n-1,

LCM of 1 to n  = LCM( x, n)

 

Given x = p1^d1 + p2^d2 + ... + pn^dn,

For any number n = p1^c1 + p2^c2 + ... + pn^cn,

we know that ci <= di for all i,

unless n is a perfect power of a prime.

 

This can be proven easily using induction.

 

Also, if n is not a perfect power of a prime, then it is easy to prove that LCM(n, x) = x

 

Therefore, we only need to work on the perfect powers of prime.

 

My code which generates primes dynamically and their powers dyanmically got AC in 1.5s.  Anyone who can do better please tell me how...

 

 

 

Wednesday:

 

10544: Solve it using DP.

 

 

 

junbin

Questions attempted: 10673 - 10680
 
Questions solved:
 
10673
10677
10678
10679
 
 
Discussion:
 
10673: There is a very simple formula which involves p, q, x and k.
 
Note that there are only 2 cases: ceil(x/k) = floor(x/k) or ceil(x/k) = floor(x/k)+1
The first one is trivial.  The second one can be solved using the formula.
 
 
10674: Geometry question.  As far as we can tell, there are 5 cases:
 
1: One circle is completely inside another and there are no intersections (0 tangents)
2: One circle is completely inside another and both circles touch at a point (1 tangent)
3: Both circles straddle each other (2 tangents)
3: Both circles are outside of each other, but touch at a point (3 tangents)
4: Both circles are completely distinct (4 tangents)
5: Both circles are the same (infinite)
 
However, no one managed to get AC, though Mengran was pretty close.. we believe it was just some simple typo's.
 
 
10675: I apologise for the dicussion we had regarding this question.. there can be non-integer answers.  Therefore, the algorithm I talked about will not work.
 
10676: We think this is just a simple brute-force/greedy method, but because of the complicated rules, no one attempted it.
 
10677: Brute force, very easy.
 
10678: Area of ellipse = pi * a * b
 
10679: String matching problem.  Using standard string matching (O(n^2)) will definitely TLE.
 
You need something along the lines of KMP to get AC (8s)
 
I'm sure there are better methods of solving this question, but we have yet to come up with something.  Anyone has any ideas, please post.
 
10680: I think DP will work, but may be too slow.  More details when I AC.
 
 
junbin

Questions attempted:

10544 Numbering the Paths

10545 Maximal Quadrilateral

10546 The Eagle's Nest

10547 Hidden Truth in Recurrence

10548 Find the Right Changes

Attendance: Melvin,
Stephanus, Bang, Hoang

10544 : Done by Melvin
10545 : I think this problem has direct formula, but I don’t remember. Anyway, Bang came up with an equation that can be solved by binary search.
10546 : After looking board, I got ACC =P, I think that the technique is very good, read if you get stuck.
10547 : No one did this
10548 : Melvin and Bang came up with his number theory solution.

As discussed, first we find maximum length K by using Longest Increasing Subsequence.
The next problem is how do we choose the correct Subsequence so that it won’t break any other subsequence.
We can’t pick any subsequence, here is the counterexample (from board) :

9

a1   7

a2   5

a3   1

a4   15

a5   13

a6   8

a7   16

a8   10

a9   9

0

 

If we greedily choose a3,a6,a7(1,8,16) then we cannot choose any other LIS of length 3. But as you'd see we could easily play 6 missions in two games a1,a4,a7(7,15,16) and then a2,a6,a9(5,8,9).

Actually the answer for this problem is : maximum_number_of_disjoint_LIS x K
Fortunately, we can find maximum_number_of_disjoint_LIS using maximum flow, here is the setting (from board):

Construct the network as follows:

For each mission make two vertices. From the 1st vertex connect using a unit edge to the 2nd vertex of the missions that appear before this mission and are easier than the one at hand. Then connect the 2nd vertex of the current mission to the 1st vertex of the current mission. From the source connect to the 2nd vertex of the missions that can be chosen as the K th mission in some LIS. And from the 1st missions of the LISs connect to the sink. Now run a max flow from source to sink.

 

The answer would be K*max-flow.

regards,
stephanus

 

After a lot of debugging, I finally solved 10563.
 
The solution is 2 parts, first part is to calculate the largest sized square that can fit into a region starting at point x, y.  This is calculated using DP.
The 2nd part is to fill in the map, this is done using greedy.
 
 
1:
 
The method to determine the largest sized square at a point was described in previous mails, and You Quan gave a very good improvement on my own.
 
Define F(x, y) = the largest sized square that can be formed with the top right corner at (x, y)
 
 
2:
 
The most important thing to realise is that we have to fill in the map such that the result is lexicographically smallest.  In other words,
 
(1, 1) is the most important sqr,
(1, 2) is next and so on.
 
In general:
 
(x, y)  is better than (a, b)   if   x < a   or if (x == a && y < b)
 
 
This gives us a very nice greedy method where by we loop through row major order from left to right.   At each point, we determine the smallest alphabet that can fit.  Then we determine if the previous square has a smaller alphabet.  If it does, we use the result of part 1 to determine if we can turn the previous square and the current square into a bigger square.
 
Note:
 
When filling (x, y)
 
(x-1, y) may or may not be filled
(x+1, y) may or may not be filled
(x, y-1) may or may not be filled
(x+1, y) is definitely not filled.
 
 
 
 
junbin
 
ps: Attached is the sample input/output file I used to test my own program.  Getting all correct will not gurantee AC, since my program got all correct when it still had a small bug.  I did not create a sample data for that last bug since I've already got it AC'ed. :p

 
Junbin wrote:
>>10564:
>>DP / Brute force with memoization, though using standard DP technique
>>may be too slow unless you use a link list.

link list ?? I didn't use any for my program anyway an array is fast enough, I would advise against using complicated data structures (espcially dynamically allocated ones) as far as possible unless there is an order of magnitude improvement in complexity as it take more time to code and debug. A simple NumPaths[row][col][sum] is suffcient where NumPaths[r][c][s] is the number of paths starting at row r and column c and ends in the last row with sum s. In this case memoization would be more efficient then dp as there is no need to compute for all possible values of sum from 0 to 500.

Melvin


 

Questions attempted: 10557, 10559 to 10564
 
Questions solved:
10557
10560
10562
10564
 
 
 
Discussion
 
10557:
Very simple maze searching question.  Just us DFS, everytime you encounter a cycle, and the current energy level is higher, then set the current enegy level to infinite, and avoid this node in the future.
 
 
10560:
If you solve the question a bit, you should be able to find a very simple pattern to how the numbers are organised.
 
 
10562:
Standard parsing question.  Not much is required other then simple recursion.
 
10564:
DP / Brute force with memoization, though using standard DP technique may be too slow unless you use a link list.
 
 
 
10559:
Possible brute force with memoization methods.
 
10561:
Possible DP method.  Brute force with memoization will not work, unless you find some way to dramatically reduce the number of states you need to memoize.
 
10563:
Greedy will not work, at least, without a lot of special case handling.  Simple counter example:
 
??????
x?????
xxx???
 
(x = don't fill, ? = fill)
 
Greedy will produce answer:
 
ABBCCC
xBBCCC
xxxCCC
 
 
but optimal answer is:
 
ABAABB
xCAABB
x
xxBAC
 
I have thought of a way to attempt this qn, but I haven't tried it yet.. will give news if I get it AC'ed
 
 
junbin

I think the two newcomers did not get melvin's email, and since I have somethings to add, you're gonna get spammed again. :)

10581 : There is a 2d DP recurrence for the same data stored.

Consider f(a, b, c) Which is to partition a into b partitions, using at least c or more.

This can be converted to f( a - (b*c), b, 0)

Since all f(a, b, c) can be converted, we can have a 2d table, which increases lookup speed as well as decreases memory requirements. This is also very similar to the n^2 algorithm I talked about, but I can't find the formula right now, though I think it's on the forum somewhere.



10586 : Use a 10001 elements array and work on it.. My code is about 20 lines long and runs in 0.082s.. I think Melvin might have hit some snag
somewhere. :p Anyway, since this is a pretty easy question and processing
is very fast, it is likely that there are many many many test cases. If you get a slow timing or even TLE, try switching to scanf/printf.


10588 : Unless Melvin solved it using the method he described, I can safely say that that method will NOT work. :p Simple counter example:

Consider 1000 people, 1000 doctors. All of the people visit at time 0. All of them visit 1000 doctors and all 1000*1000=1000000 million doctors are doctor number 1.

For my implementation (which is exactly what melvin described), it takes about 3 seconds to process every 1000 time units.

In each time unit, only one person visits the doctor, all 999 others are rescheduled.
Therefore, total time taken is 1 million time units (plus minus one or two) and total re-schedules = 999 000 000 (plus minus a bit).

Very very slow. :p

From what I read from the board (there's only 2 posts, so don't hang on it too much), you have to find some sort of recursive formulation to determine collisions and then work from there.




junbin



Ps: For the IOI people, you are encouraged to work on these problems as well. I'll post you a separate email about your questions today.


-----Original Message-----
From: Zhang Zhiyong,Melvin [mailto:u0200778@nus.edu.sg]
Sent: Saturday, 19 June, 2004 10:02 PM
To: Teng Junbin; Zhou Junyu; Cai Junfu; Daniel Chia; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sim, Yan Chuan; Sing Kiat Oh; Stephanus; Steven Halim; Wailun Tam; Wang Zirui; You Quan Chong
Subject: Training on Sat 19 June


Hi all,

Sorry for the previous email, I accidentally hid the wrong button and
sent the mail before I finished typing. Anyway, as mentioned problems
attempted were 10581 - 10588.

Solved all except for 10588.

Discussions:

10581 - I really feel like tearing my hair out, my solution is correct
except for a stupid mistake of a wrong variable, anyway its quite fast <
0.05s using a single 3D DP table to store the number of ways to sum up to m,
using n number where each number is at least k. A simple recurrence is
f(m,n,k) = f(m-k, n - 1, k) + f(m, n, k+1) with several trival cases to take
care of. The rest is boils down to determining each number iteratively
starting from the smallest by checking with k and the DP table

10582 - Some problems with reading the input as there are 6 kinds of
possible tiles that can be given although the sample input only showed two,
the rest is use brute force to count the number of solutions on the at most
64 squares board, be careful that in a solution a tile can only be turned
once.

10583 - Easy, a disjoint set problem, use the union find data structure

10584 - Trickly text replacement problem, make sure you follow the problem
statement exactly especially for contractions, the rest is basically string
manipulation

10585 - Easy geometry problem, the center of symmetry if it exists must be
the centre of the set of points and this can be found by taking the average
over all the x and y values. Then you need to double check that it is
indeed a center of symmetry by finding the dual of each point about the
center of symmetry, use a hashtable to check if a point exists to speed
things up.

10586 - Use the standard high school polynomial division algorithm, though
you may need to tweak your represenation of the polynomial a bit to make it
efficient enough. I just used a 10001 element array to represent a
polynomial, its works but barely passes the time lime, clocks in at 9.4s
probably due to a lot of copying.

10587 - Since the range of the segements is too large, we need to discretize
the problem by considering only the endpoints of each poster, then sort them
in increasing index and do a plane sweep. Maintain a list of posters
currently under consideration and the poster which is on top and a bit
vector to remember which posters have been seen, update the corresponding
data structures when you encounter a left end or right end of the poster.

10588 - Complicated simulation problem, maintain n queues to represent the
people queueing at each doctor's office and a priority queue for the events,
each event is characterized by 4 parameters, the id of the patient, is it a
visiting or leaving an office, the office number and the time of the event.
At the start, populate the priority queue with n visiting events, then
proceed to simulate each event and update the queues accordingly as the
simulation proceeds. Take care when several patients visit the same office
at the same time, then they must enter the queue of the office in increasing
patient id number.

Junbin: Could you forward this to the two vietnamese students, I just
realised that I don't know their email address.

Regards,

Melvin


Hi all,

Sorry for the previous email, I accidentally hid the wrong button and sent the mail before I finished typing. Anyway, as mentioned problems attempted were 10581 - 10588.

Solved all except for 10588.

Discussions:

10581 - I really feel like tearing my hair out, my solution is correct except for a stupid mistake of a wrong variable, anyway its quite fast < 0.05s using a single 3D DP table to store the number of ways to sum up to m, using n number where each number is at least k. A simple recurrence is f(m,n,k) = f(m-k, n - 1, k) + f(m, n, k+1) with several trival cases to take care of. The rest is boils down to determining each number iteratively starting from the smallest by checking with k and the DP table

10582 - Some problems with reading the input as there are 6 kinds of possible tiles that can be given although the sample input only showed two, the rest is use brute force to count the number of solutions on the at most 64 squares board, be careful that in a solution a tile can only be turned once.

10583 - Easy, a disjoint set problem, use the union find data structure

10584 - Trickly text replacement problem, make sure you follow the problem statement exactly especially for contractions, the rest is basically string manipulation

10585 - Easy geometry problem, the center of symmetry if it exists must be the centre of the set of points and this can be found by taking the average over all the x and y values. Then you need to double check that it is indeed a center of symmetry by finding the dual of each point about the center of symmetry, use a hashtable to check if a point exists to speed things up.

10586 - Use the standard high school polynomial division algorithm, though you may need to tweak your represenation of the polynomial a bit to make it efficient enough. I just used a 10001 element array to represent a polynomial, its works but barely passes the time lime, clocks in at 9.4s probably due to a lot of copying.

10587 - Since the range of the segements is too large, we need to discretize the problem by considering only the endpoints of each poster, then sort them in increasing index and do a plane sweep. Maintain a list of posters currently under consideration and the poster which is on top and a bit vector to remember which posters have been seen, update the corresponding data structures when you encounter a left end or right end of the poster.

10588 - Complicated simulation problem, maintain n queues to represent the people queueing at each doctor's office and a priority queue for the events, each event is characterized by 4 parameters, the id of the patient, is it a visiting or leaving an office, the office number and the time of the event. At the start, populate the priority queue with n visiting events, then proceed to simulate each event and update the queues accordingly as the simulation proceeds. Take care when several patients visit the same office at the same time, then they must enter the queue of the office in increasing patient id number.

Junbin: Could you forward this to the two vietnamese students, I just realised that I don't know their email address.

Regards,

Melvin

 

10665 : 
 
Simple ad-hoc problem, be careful of the lexicographic requirements. 
 
Why the answer for sample input
 
10
PDJFGEDFANGEHIAEJBHJGEDGJGJEINDFJHEIEDGHFFGHDHGFHAJGIE#
 
is (1)

E H D A B C I F J G
8 7 6 3 1 0 4 6 7 9

not (2)

E H D A B N I F J G
8 7 6 3 1 2 4 6 7 9

Because if you sort the input based on weight and char then try to put the workers
descendingly, you will get (2) not (1).

What's the objective of this problem actually? I don't understand. Thx in advance.


regards,
stephanus  

I was wrong. I can fit at most 1500 strings of length 30+ in a 40KB file. There are still more than 3500 answers to be computed. That will take around 5 seconds.

 

-----Original Message-----
From: Wang Zirui
Sent: Thursday, June 10, 2004 2:25 PM
To: Zhang Zhiyong,Melvin; Stephanus; 'Daniel Chia'; 'Teng Junbin'; 'Zhou Junyu'; Cai Junfu; 'Guo Yunsong'; 'Junjie Liang'; 'Kah Keng Tay'; Li Mengran; Liu Chang; 'Melvin Zhang'; 'Sing Kiat Oh'; 'Steven Halim'; 'Wailun Tam'; 'You Quan Chong'
Subject: 10590 - Boxes of Chocolates Again

 

Hi everyone,

 

I used a knap-sack like DP. The difference is that knap-sack DP fills the array from the end to the front, but in this question it has to go from the front to the end. Accepted in 9.035 seconds. If I were in the contest, I would just send in a precal table; 5000 strings can’t be much, right?

 

Regards,

Zirui

 

-----Original Message-----
From: Zhang Zhiyong,Melvin
Sent: Wednesday, June 09, 2004 6:51 PM
To: Stephanus; Wang Zirui; Daniel Chia; Teng Junbin; Zhou Junyu; Cai Junfu; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sing Kiat Oh; Steven Halim; Wailun Tam; You Quan Chong
Subject: RE: Training on Wed 09 June

 

Ok, finally got AC on 10590, its easy if you know the formula, extremely difficult otherwise.

I think most people can figure out a 2D DP formulation for finding the number of ways which incidentally is the same as the number of integer paritions of a number.

 

Denote f(n,k) by the number of ways to sum to n where each term is at most k

then

f(n,k) = f(n-k, k) + f(n, k-1) if k <= n

f(n,k) = f(n, n) if k > n

f(0,k) = 1

f(n,0) = 0

 

There is a problem with this because we need 5000 * 5000 big integers to store all the values in the DP table.  Actually you'll notice that only two rows are necessary to compute f(n,k) so we can reduce the space complexity to linear but this means for each input we need to compute everything again which may lead to TLE.

 

The safest way to to use a 1D DP formulation based on the following recurrence, where P(n) denote the number of ways to pick the chocoloates

P(n) = P(n-1) + P(n-2) - P(n-5) - P(n-7) + P(n-12) + P(n-15) .... while the n - k term is non negative

P(0) = 1

The terms are obtained using the formula k * (3 * k - 1) for k = 0, +1, -1, +2, -2, +3, -3 ....

The sign goes from +, +, -, -, +, +, -, - ....

 

Regards,

Melvin

-----Original Message-----
From: Stephanus
Sent: Wed 6/9/2004 4:52 PM
To: Wang Zirui; Daniel Chia; Teng Junbin; Zhou Junyu; Cai Junfu; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sing Kiat Oh; Steven Halim; Wailun Tam; You Quan Chong
Cc:
Subject: Training on Wed 09 June

Today’s problems are 10589-10594

10589: Area
Very easy problem, everyone can do, notice that there’s type, area should be m*a*a/n

10590: Chocolate Box
I got TLE. Maybe can ask Melvin for formula?

10591: Happy Number
I did this quite long time ago, should be memoization?

10593: Kites
At last, I got ACC, first time is 5.598 sec, after optimization 4.232 sec. I still don’t get ACC for real contest. Any idea?
My idea :
Do a brute force check, first check the squares then check the kites

for each cell (i,j) I have this array

down[i][j],up[i][j],left[i][j],right[i][j]
It means from i,j how many steps can you go (down/up/left/right).

int count;
ß counter for answer

1.check the squares
   I represent square by it’s upper left corner and size(height,width)
   xxx
   xxx
   xxx
   is a square with upper left (1,1) and size(3,3), if you can find the largest square with
   upper left (1,1) then total number of square with upper left corner (1,1) is (3 – 1=2),
   because we don’t want 1x1 square so we subtract 1.

   so in general if you find a largest square with upper left (i,j) and size(n,n), you can get
   n – 1 squares.

   maximum size of square can be formed from cell (i,j) is min(right( i,j) , down( i, j) )
    for maxsize downto 2
        if square can be formed
              count += size – 1;        // minus 1 because we don’t want 1x1 square
              break;                         // we have the largest square then break

2. check the rhombus
    I represent rhombus by it’s center and it’s size, e.g
     .x.
     xxx
     .x.
   will be rhombus formed by it’s center (2,2) with size 2

    for each cell (i,j)
    assume that (i,j) is the rhombus’ center, then the maximum size of a rhombus is min(down[i][j],up[i][j],left[i][j],right[i][j])
    for maxsize downto 2
         if square can be formed
                count += size – 1;     // minus 1 because we don’t want 1x1 rhombus
                break;                      // we have the largest rhombus then no need to count the smaller one
   

regards,
Stephanus

There is a slightly faster method to solving this question and involves 6 dp tables (yes 6).
 
The timing which I got is 2.8s, which is still very slow compared to the less than 0.5s from the top 25, so if anyone can come up with something even faster, please tell us about it.
 
My idea is based partly on what I overhear Zirui and Stephanus discuss some time ago.
 
Define:
 
MaxD[i][j]  -> The maximum number of sequential squres down from (i, j) which are filled
MaxR[i][j]  -> The maximum number of sequential squres right from (i, j) which are filled
MaxLD[i][j]  -> The maximum number of sequential squres diagonally left-down from (i, j) which are filled
MaxRD[i][j]  -> The maximum number of sequential squres diagonally right-down from (i, j) which are filled
 
MaxSqr[i][j] -> The maximum sized square that can be formed at (i, j)
MaxDmd[i][j] -> The maximum sized diamond that can be formed at (i, j)
 
 
Use a simple i-j nested loop to calculate the first 4 tables.
 
So for a completely filled 3x3 square, we get:
 
MaxD =
3 3 3
2 2 2
1 1 1
 
MaxR =
3 2 1
3 2 1
3 2 1
 
MaxLD =
3 2 1
2 2 1
1 1 1
 
MaxRD =
1 2 3
1 2 2
1 1 1
 
 
Then using the four previous tables, we can compute the next 2 tables using another i-j nested loop
 
MaxSqr[i][j] =
 
if (i, j) is empty -> 0
else -> MIN(  MaxSqr[i-1][j-1] + 1   ,   MaxR[i][j]    ,   MaxD[i][j]   )   // min of 3
 
 
MaxDmd is harder to compute, and I'll leave it as an exercise.  It is quite similar to MaxSqr, but you need to consider two previous rows instead of just the one previous row.
 
 
junbin
I managed to solve this question.  It seems our previous solution was correct, but the precision was not good enough.  I managed to find a snippet of code on the forum (below) which uses slighly less trigo functions to determine the 4 points of each board and I got accepted.
 
 
fscanf (in,"%d",&n);
s=0;
for (i=0;i<n;i++){
    fscanf (in,"%lf %lf %lf %lf %lf",&x,&y,&w,&h,&a);
    s=s+w*h;
    a=a*M_PI/180.0;
    pnt[i*4][0]=-w/2.0*cos(a)+h/2.0*sin(a)+x;
    pnt[i*4][1]=w/2.0*sin(a)+h/2.0*cos(a)+y;
 
    pnt[i*4+1][0]=w/2.0*cos(a)+h/2.0*sin(a)+x;
    pnt[i*4+1][1]=-w/2.0*sin(a)+h/2.0*cos(a)+y;
 
    pnt[i*4+2][0]=w/2.0*cos(a)-h/2.0*sin(a)+x;
    pnt[i*4+2][1]=-w/2.0*sin(a)-h/2.0*cos(a)+y;
 
    pnt[i*4+3][0]=-w/2.0*cos(a)-h/2.0*sin(a)+x;
    pnt[i*4+3][1]=w/2.0*sin(a)-h/2.0*cos(a)+y;
}      }
 
 
 
 
 
 
junbin

Ok, finally got AC on 10590, its easy if you know the formula, extremely difficult otherwise.
I think most people can figure out a 2D DP formulation for finding the number of ways which incidentally is the same as the number of integer paritions of a number.

Denote f(n,k) by the number of ways to sum to n where each term is at most k then
f(n,k) = f(n-k, k) + f(n, k-1) if k <= n
f(n,k) = f(n, n) if k > n
f(0,k) = 1
f(n,0) = 0

There is a problem with this because we need 5000 * 5000 big integers to store all the values in the DP table. Actually you'll notice that only two rows are necessary to compute f(n,k) so we can reduce the space complexity to linear but this means for each input we need to compute everything again which may lead to TLE.

The safest way to to use a 1D DP formulation based on the following recurrence, where P(n) denote the number of ways to pick the chocoloates
P(n) = P(n-1) + P(n-2) - P(n-5) - P(n-7) + P(n-12) + P(n-15) .... while the n - k term is non negative
P(0) = 1
The terms are obtained using the formula k * (3 * k - 1) for k = 0, +1, -1, +2, -2, +3, -3 ....
The sign goes from +, +, -, -, +, +, -, - ....

Regards,
Melvin
-----Original Message-----
From: Stephanus
Sent: Wed 6/9/2004 4:52 PM

10590: Chocolate Box
I got TLE. Maybe can ask Melvin for formula?

10593: Kites
At last, I got ACC, first time is 5.598 sec, after optimization 4.232 sec. I still don’t get ACC for real contest. Any idea?
My idea :
Do a brute force check, first check the squares then check the kites

for each cell (i,j) I have this array

down[i][j],up[i][j],left[i][j],right[i][j]
It means from i,j how many steps can you go (down/up/left/right).

int count; <-- counter for answer

1.check the squares
I represent square by it’s upper left corner and size(height,width)
xxx
xxx
xxx
is a square with upper left (1,1) and size(3,3), if you can find the largest square with
upper left (1,1) then total number of square with upper left corner (1,1) is (3 – 1=2),
because we don’t want 1x1 square so we subtract 1.

so in general if you find a largest square with upper left (i,j) and size(n,n), you can get
n – 1 squares.

maximum size of square can be formed from cell (i,j) is min(right( i,j) , down( i, j) )
for maxsize downto 2
if square can be formed
count += size – 1; // minus 1 because we don’t want 1x1 square
break; // we have the largest square then break

2. check the rhombus
I represent rhombus by it’s center and it’s size, e.g
.x.
xxx
.x.
will be rhombus formed by it’s center (2,2) with size 2

for each cell (i,j)
assume that (i,j) is the rhombus’ center, then the maximum size of a rhombus is min(down[i][j],up[i][j],left[i][j],right[i][j])
for maxsize downto 2
if square can be formed
count += size – 1; // minus 1 because we don’t want 1x1 rhombus
break; // we have the largest rhombus then no need to count the smaller one


 

You can also find a closed form (without summation sign) of the expression and then use log(N) time to evaluate it. Restricted to age 17 and above, as you need to know geometric progression and differentiation.

-----Original Message-----
From: Daniel Chia [mailto:danielcjh@yahoo.com.sg]
Sent: Saturday, June 05, 2004 11:02 PM
To: Teng Junbin; Zhou Junyu; Cai Junfu; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sing Kiat Oh; Stephanus; Steven Halim; Wailun Tam; Wang Zirui; You Quan Chong
Subject: Re: Training on Saturday 05 June

 

Actually, for 10523, DP or memoization is not really required. The formula can be simplified to

 

 

A(1 + A(2 + A(n-1 + nA)))

 

According to JJ its horner's rule i believe. Correct me as i am wrong. As such you can start from the innermost bracket and just work your way out, using only multiplies and adds. And since nA is always less than 10000, you can implement a big number multiply rather easily using base 10000 digits.

------------------------------------------------------------------------
Daniel Chia




> ----- Original Message -----
> From: Teng Junbin
> Sent: Saturday, June 05, 2004 19:42
>
> Questions attempted: 10519 - 10525
> I can't remember who solved which questions, but I can proudly say
> that all questions were solved by someone or other :)
>
> Before I go on, I feel I have to apologise for choosing these very
> very poor questions. In future, I suggest we do not use Bangladeshi questions for practice, the reasons are:
> 1) The english is terrible. Most of the questions are ridiculously
> easy, but because the english is so bad, most people miss out important points.
> 2) The questions don't make sense. For example, asking you to find
> the inverse of a matrix, but only if you can do it without swapping
> rows (and the way they say this condition) is ridiculous.
> 3) The test data is wrong. The test data for 10525 is wrong. Details later.
> 4) The specification is vague. Most (if not all) of the questions
> do not give a specific description of input/output. The most glaring
> one is the matrix question, which doesn't even say that input can be floating point (they can) and output has to be to 6 dp (it does)
> 5) It's too easy.
> 6) Input to your question can contain weird values like 00005
> (10521)
>
>
> 10519: This is a pretty easy question, just have to work out the formula (n^2 - n + 2).
> Special case, for 0, the answer is 1.
>
> 10520: The description is vague, the formula is complicated, but
> just use brute force with memoization and you'll have no trouble with
> it. Note that the specification for the formula is WRONG. If you
> follow the formula strictly, you'll get an infinite loop. The formula
> should have j > 1 instead of j > 0 (since a(4, 1) will call itself
> otherwise)
>
> 10521: Define a function x( p , q ) and do:
>
> print the quotient of p/q (rounded down)
> then call x( q , ( p % q) )
>
> recurse until p is a multiple of q, at which point, just print p/q
>
>
> 10522: This is a mathematical/geometric question. I'm sorry to say
> I haven't figured out the formula, but Zirui has. However, he did not
> managed to finish the question in time. Wailun
> (IOI) mangaed to solve the question, but he had to leave early so he
> didn't have time to explain how he did it. If Zirui/Wailun can enlighten us, that'd be great.
>
> 10523: It is very easy. Just remember to use memoization/DP because
> there is a lot of test cases.
>
> 10524: Simple question, given a matrix, find it's inverse. Use
> gaussian matrix reductrion strategy. Note that you CANNOT swap rows.
> If you cannot find the inverse without swapping rows, then the answer is not possible, even though mathematically, it's possible.
>
> 10525: This is the question that gives me the worst headache. It
> appears that the question is wrong. You have to minimize time before
> you minimize distance (there is one line that says this, but the rest
> of the whole question implies otherwise). Also, when there is more than one road between two points, use the last one in the input, even if this is not the optimise road.
>
>
>
>
> junbin

 

Actually, for 10523, DP or memoization is not really required. The formula can be simplified to
 
 
A(1 + A(2 + A(n-1 + nA)))
 
According to JJ its horner's rule i believe. Correct me as i am wrong. As such you can start from the innermost bracket and just work your way out, using only multiplies and adds. And since nA is always less than 10000, you can implement a big number multiply rather easily using base 10000 digits.
------------------------------------------------------------------------
Daniel Chia
 
 
I managed to solve this question.. and I realised there are a few tricks which are not mentioned.
 
First, the solution.
 
Given the rules, and given the end result of applying the rules, we can use brute force to try to reduce the end result into the start string.
 
It is very simply a case of string malnipulation.
 
 
Now's here's the trick.  The question description is wrong.  One hell of a trick huh? :)
 
Instead of terminating the rules section with # -> #, look for ANY line with a # in it, or ANY line without a -> in it.
 
If it's a line without the ->, then process it as if it's a terminal string.
 
 
As for the terminating strings section, this section is terminated by ANY line with a # in it (not necessarily first char) or by end of file.
 
 
 
junbin
Questions attempted: 10595 - 10599
 
Those who took CS3233 last sem already did 10595, so we skipped it (only Yunsong attempted it)
 
Questions solved:
 
10596 : GYS, MZZY
10598 : GYS, MZZY, WZR
10599 : GYS, WZR
 
I think I may have gotten some of the data above wrong.. correct me if I did.
 
 
Solution:
 
10595:
Simple BFS, the hard part is the modelling.
 
10596:
This question is tricky (and wrong in my opinion).  The question seems to be asking if a given graph is can form a Eulerian circuit, but instead, you have to make sure 2 things:
 
1) Eulerian circuit is possible
2) ALL VERITICES ARE CONNECTED.
 
The second point is not strictly necessary for an Eulerian circuit, but is necessary for this question (though not mentioned)
 
10598:
Anyone who's not a blind idiot (aka me) and saw the hint at the bottom should be able to figure out how to do this... Simple geometry question, just be careful of the ordering of the latitudes.
 
10599:
Dynamic programming solution.
Define Count(a) as maximum number of garbage we can collect after reaching point a
Define Ways(a) as number of ways to reach point a given that we collected Count(a) garbage
 
Note: a = (x * number_of_cols) + y + 1, x and y are 0-offset
 
Count(a) = Max { Count(w) }  where w is any point that can reach a
Ways(a) = Sum{ Ways(x) } where x is any point that can reach a AND has Count(x) = Count(a) -1
 
 
10597:
No one solved this in time, but one possible solution I'm working on now is based on brute force.
 
 
 
 
 
junbin

Matrix multiplication is helpful in various transformation problems. The reason is that running time can be turned down to log(n) quite easily. Some examples:

 

In Introduction to Algorithms, there is an all-pairs shortest paths algorithm that makes use of the same idea that we have seen in 10655 Contemplation! Algebra, in Section 25.1 Shortest paths and matrix multiplication.

 

There is another problem, 306 Cipher, which on the surface has little to do with matrices. But it is also about transformation; hence the same idea is applicable. Can you give a log(k) algorithm?

10652 : Board Wrapping
 
I think this should be a pretty simple question.  Using geometry, get the four corners of each rectangle, perform a convex hull on all 4 * n points.  Answer = (total area of rectangles / area of convex hull) * 100
 
 
However, I keep getting WA, so I believe either my understanding of the question is wrong or I have a floating point error somewhere...
 
 
 
 
 
 
10658 : reArrange
 
I managed to solve this using DP of 3 tables (Yunsong did it with 2 tables)
 
Define:
 
Mustmove[x] = number of moves it takes to sort x tiles given that the bottom-most tile MUST be moved to another location  (this is not the answer)
Answer[x] = number of moves it takes to sort x tiles given that the bottom-most tile MUST NOT move (this is the answer)
Hanoi[x]  = number of moves it takes to move x tiles from one stack to another (this is exactly the same as the tower of hanoi problem, hence the name)
 
 
Hanoi[x] = ( Hanoi[x-1] * 2  ) + 1    //  If you don't understand this, please refer to explanation of tower of hanoi solution by DP, this can be found easily on google
 
Mustmove[x] = Hanoi[x-1] + 1 + Answer[x-1]
 
Intuitively, it means that
 
Starting with x tiles on stack 1
Step 1:  We move the topmost x-1 tiles to stack 3
Step 2: We move the bottommost tile to stack 2
Step 3: We sort the topmost x-2 tiles on stack 3 (leaving the x-1'th tile on stack 3)
 
 
Answer[x] = Hanoi[x-2] + 1 + mustmove[x-2]
 
It means tat
 
Starting with x tiles on stack 1
Step 1: We move the topmost x-2 tiles to stack 3
Step 2: We move the x-1'th tile to stack 2  (thus sorting the bottommost 2 tiles)
 
Since the bottom most two tiles are sorted, and every other tile can be put on them, we can effectively ignore the bottommost two tiles and just sort the topmost x-2 tiles.  Note that since we define the first 2 stacks as the ending points, therefore, we use mustmove[x-2]
 
 
 
 
junbin
Questions attempted: 10651 - 10658
 
Questions solved:
 
10651 
10653  
10654 
10656  
10658 
 
 
Additionally, I managed to solve 10655 at home.
 
 
Discussion:
 
10651 : Simple brute force with memoization or dynamic programming question.
 
10653 : Simple maze solving, use a queue.
 
10654 : Simple brute force with memoization or dynamic programming question (very simiilar to 10651)
 
10656 : Trivial.
 
10658 : Ask Yunsong, I will post more if/when I solve it.
 
10655 :
 
This is a very tricky question in a lot of ways.
 
1) a and b can be complex
2) Input is terminated by a line with 2 zeros.  This does NOT mean that input such as "0 0 3" are illegal!
3) 0^0 is illegal, but  a ^ 0 where a != 0 is not (ie:  "5 5 0" is a legal input, answer is 2)
 
To pass time limit, you need a solution in the order of log n.
 
Number theory:
 
Let Xn = a^n + b^n
Let s = a + b  (sum)
Let p = ab  (product)
 
X0 = 2
X1 = a + b
Xn = sX(n-1) - pX(n-2)
 
The simplest method is to use the O(n) method and at each stage, store Xn-1 and Xn-2  so that Xn can be evaluated.
 
The log n method is slightly more complicated and involves matrix malnipulation
 
 
Let M = (  s   -p  )      [ 2x2 matrix, note that p is negated ]
            (  1    0  )
 
Let Vn = (  Xn   )    [ 2 row, 1 col matrix)
             (  Xn-1 )
 
Let W = (  X1 )    [ 2 row, 1 col matrix)
            (  X0 )
 
 
Observe that:
 
MVn = Vn+1       (since s * Xn - pXn-1 = Xn+1  )
 
MW = MV2
 
Therefore
 
M ... M  W = Vn
 
Where   M ... M denotes M^(n-1)
 
 
So, by finding M^(n-1), we can solve the question. 
I leave it up to you to find  M^(n-1)  in O( logn )  time
 
 
hint:
 
to find a ^ b  (a, b are integers)
 
if b = 0, return 1
if b = 1, return a
if b is even,  return  (  a ^ (b/2)  ) ^ 2
if b is od,  return  ( (  a ^ (b/2)  ) ^ 2 )  * a
 
 
 
 
 
junbin

There is a serious flaw in my integer programming formulation below. Can you find it?

 

-----Original Message-----
From: Wang Zirui
Sent: Wednesday, May 26, 2004 3:53 PM
To: 'Teng Junbin'; Zhou Junyu; Cai Junfu; Daniel Chia; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sing Kiat Oh; Stephanus; Steven Halim; Wailun Tam; You Quan Chong; Leung Ngai-Hang Zachary
Subject: Training Summary (Wed, 26 May)

 

Hi everyone,

 

Today we tried to solve Problems 10628 Quadrills, 10629 Truckin’, 10630 Millennium Ceremony and 10631 Normals <http://acm.uva.es/cgi-bin/OnlineJudge?Volume:106>. They are quite hard, judging from the low numbers of acceptance, but we managed to work out some ideas about 10631 and 10629.

 

10631: Testing whether a point on the ellipse satisfies the condition that its normal passes through point (p, q) is simple; we can find the equation of the normal, substitute x by p and see if we get approximately q. Similarly, it is possible to use the line passing through point (p, q) and parallel to a normal to check against the normal’s foot of perpendicular. Or compare the gradient of a normal and of the line connecting the two points.

 

The challenge lies in searching for such a point. Our discussion has brought out two ideas. The first uses binary search, based on the argument that, for a guessing point A on the ellipse, if the line passing through point (p, q) and parallel to the normal at A cuts the ellipse at a point to the left of A, the next guess should also be to the left of A; and vice versa. But this method fails when two solution points lie closely to each other, because they look the same as no point is there! Hence the second method of carpet search comes to rescue. But its efficiency is a problem. (If you have a working method or formula, I would like to urge you to publish it to us all.)

 

10629: The most advanced result on this problem seems to be that it is an integer programming problem. The formulation is as follows:

 

minimize: ti(vi + 1/vi – 0.1), i = 1, 2, …, L,

subject to:

ri + ni (ri + gi) ti (ri + gi) + ni (ri + gi),

    ti * vi = di,

    ni 0, and ni is integer, for i = 1, 2, …, L.

 

Integer programming is based on linear programming and branch and bound. Introduction to Algorithms has a concise introduction to linear programming, in case you need more information. Again, if anyone has better ideas, discussion is always welcome.

 

Hope I haven’t ruined the training summary tradition when Junbin is not around.

 

Regards,

Zirui

I've spent some time on the two questions and I figured it's not really worth the time. :p
 
10606:
A quick check on the forum shows that:
1) You need to solve about 100-150 maximum queries per second to NOT get TLE (ie: be able to solve 1000+ 10^100 in 1s)
2) You need a n^2 algorithm (this includes your multiplication/binary search/division, depending on which way you are doing)
 
 
 
10607:
There was a solution posted in the forums, a quick look at it and I think it's wrong.. basically the solution given is:
 
1) Find the number of states connected to the capital
2) Use Dijkstra to find minimum path from outside to the capital
3) If the capital is a donut, print -1
4) If not, print shortest path to capital - 2 + number of states connected to capital
 
 
The last step, I feel is wrong.   A simple counter-example would be if the states surrounding the capital are disjoint, so you need two or more shortest paths.
 
eg:

BBBBBBB
BBHHJBB
BBHCJVB
BBEADVB
BBBFKVB
BBBBBBB
 

Answer should be:  CDEFBHK = 7
 
Answer given by above alogrithm:
 
Shortest path to capital = 3 (BEA)
Number of surrounding states = 4 (CDEF)
Answer = 3 - 2 + 4 = 5
 
 
Anyway, as far as I can tell, you need to use brute force to find the best way to join a few sets together.  These sets are the disjoint sets of the surrounding states (if two surrounding state are touching each other, they are considered as one set)  and the outside world (a set by itself).  Since, selecting a state may result in the the lowering of costs for another joining of disjoint sets, therefore brute force or recursion of sorts is required. 
 
 
But then again, since the algorithm above was accepted, the test data probably isn't too evil. :)
 
 
junbin
 
First off, I apologise to Daniel for missing out his name for the last post.. apparently I missed your name when adding the IOI people to my mailing list. :p
 
 
 
Questions attempted: 10600 - 10608  exclude 10604
 
 
Sovled: (Only for ACM team)
 
Tm1 : Yunsong, Melvin
Tm2 : Zirui, Mengran, Junbin
 
10600 : Tm1
10602 : Tm1
10603 : Tm1
10608 : Tm1
 
Tm2 solved all 4, 6 months ago *grin*
 
 
 
Solution:
 
10600:
Minimum spanning tree for 1st cost, brute force + MST (loop through all edges in 1st MST, remove one and find new MST) for second cost
 
10602:
Greedy, minimize deletions
 
10603:
Brute force
 
10608:
Disjoint set operations + counting
 
For IOI people:
10604 (Not included because the ACM people have already done it before):
Brute force with memoization / BFS
 
 
 
Discussion:
 
10605 : Brute force + greedy
10606 : Binary search
10607 : Brute force + pruning
 
 
 
 
junbin
 
ps: I'm working on 10606 and 10607.  If I solved them, BIG if, I'll mail you again. :)

After trying for few days, at last I got it correct =).
My method is memoization

f(i,L,R,last)
seq[] = the sequence given
i = the i-th character of the sequence
L = position of Left foot
R = position of Right foot
last = last foot used

the method is simple : just try all possible L,R position which is UP, LEFT, DOWN, RIGHT

f(i,L,R,last)
min of {
// do nothing
if seq[i] == DOT then f(i+1,L,R,DOT)
// use left foot
for all possible position of left foot LF
f(i+1,LF,R,LEFT)
// use right foot
for all possible position of right foot RF
f(i+1,L,RF,RIGHT)
}


t makes me need few days, because i think when the i-th character is '.' (DOT), I think I need not to try all possible L,R.

regards,
stephanus

How about double-ended BFS?

Each guy has 900 possible locations, so total 810K states which can be hashed with the square of the max possible distance, which can fit in int (30*30).

Then starting from both Houses and both Schools (working backwards), to generate all the states possible without collisions. A collision of a path from Houses and a path from Schools means a possible solution, so choose smaller of the distances.

Double-ended BFS would be about 4x faster than normal BFS. If you can generate the states using priority queue such that no state will be "overwritten" with better values (like Dijkstra), then you can recover the path later, I think. Not very sure on that. Or can do some approximation function also like A* search to close in on the answer faster.

Just some thoughts.

KK

--- Teng Junbin <tengjb@singnet.com.sg> wrote:
> Method discussed:
>
> G = Jill, J = Jack
>
> let min(Jx, Jy, Gx, Gy) = minimum distance between J and G if at some
> point in time, J is at (Jx, Jy) and G is at (Gx, Gy)
>
> Therefore,
>
> min(Jx, Jy, Gx, Gy) =
>
> Minimum of {
>
> Maximum of {
> min(Jx-1, Jy, Gx-1, Gy)
> min(Jx+1, Jy, Gx-1, Gy)
> min(Jx, Jy-1, Gx-1, Gy)
> min(Jx, Jy+1, Gx-1, Gy)
>
> min(Jx-1, Jy, Gx+1, Gy)
> min(Jx+1, Jy, Gx+1, Gy)
> min(Jx, Jy-1, Gx+1, Gy)
> min(Jx, Jy+1, Gx+1, Gy)
>
> ....
> ....
> }
>
>
> ,
>
> Distance(Jx, Jy, Gx, Gy)
>
> }
>
> In words, if J passes through (Jx, Jy) and G passes through (Gx, Gy),
> then
> the cost of (Jx, Jy, Gx, Gy) will be the maximum
> of all possible points
> that can reach (Jx, Jy, Gx, Gy). If this maximum is greater than the
> distance between (Jx, Jy) and (Gx, Gy), then we use the distance
> between (Jx, Jy) and (Gx, Gy) instead.
>
>
> Clearly, this is a DP formulation. However, because the path is not
> fixed and backtracking is allowed (eg: Jack walks EWEWEWEWEWEW),
> there is no fixed sequential way of computing the table as in normal
> DP solutions.
> Instead, we use a method similar to brute force with memoization. The
> actualy recursion is done using loop recursion (instead of
> function/stack
> recursion) since the maximum level is around 900*900, which will
> definitely give you a stack overflow.
>
> This method, in theory, should work, but in practice, is insanely hard
> and complicated to code. Go try it and you'll see. :)
>
>
>
> Another method I came up with, that should be easier to code is using
> Dijkstra's Single Point Shortest Path.
>
> We use a priority queue and prioritise according to the min function
> defined above. At any one time, we consider the point that has the
> MOST cost, ie:
> the one that has the longest distance between Jack and Jill along its
> path and then we branch off from there.
>
>
> I've made a working copy of the second method, however it is extremely
> slow.
> The memory requirement is 32mb, the time given in UVA is TLE ( > 10s).
>
>
> If anyone can come up with another method, or some form of pruning,
> please share. I'm too tired to think right now.. :p
>
>
>
> junbin
>





__________________________________
Do you Yahoo!?
SBC Yahoo! - Internet access at a great low price.
http://promo.yahoo.com/sbc/
 

Attendance:  Yunsong, Melvin, Zirui, Junbin
 
Questions posted: 10618 - 10621
 
Solved: 10620 (Everyone)
 
Discussion:
 
10618 :
 
Possible DP solution, details check with Yunson/Melvin.
 
 
10619 :
 
Possible greedy solution similar to Huffman encoding (similar means the data structure is similar, the actual implementation is very different).  Melvin and I are working on this.  Details when we solve it.
 
 
10620 :
 
Very simple brute force question, the only hard part is detecting the end condition when there is no way to reach white.  Solution: Use modulo arithmetic and store the initial x/y.
 
 
10621 :
 
Solution is brute force with memoization, but the ideology is DP.  Details when I solved it.
 
 
 
junbin

Hi,

I finally got some time to do 10638. As from the previous discussion, we need to find groups of people whose average is the same as the average of all the people (within 1 cent). Note that there're at most 10 people, so a simple brute force backtracking should do the job.

Note that during the recursion, we can only conclude that a group is 'closed' (i.e. no more people should be added) if that group's average is *exactly* the same as the average. If the average is within one cent's range, you'll fail tests like:

9.55 9.55 9.53

(if 9.55 is considered closed, then 9.53 can never be put in a group, which means you get no answer for this input)

Other than this i found everything else trivial. With a few pruning that seemed too nice and simple to miss, i got a runnig time of 0.01 sec (apparently melvin did a lot better though :P)

Btw, sorry i wasn't at sat's training. The french SEP people had to go out to buy travel insurance today :(



-----Original Message-----
From: Teng Junbin [mailto:tengjb@singnet.com.sg]
Sent: Sat 5/15/2004 7:20 PM
To: Zhou Junyu; Cai Junfu; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sing Kiat Oh; Stephanus; Steven Halim; Wang Zirui; You Quan Chong; Leung Ngai-Hang Zachary
Cc:
Subject: Training on 15 May 04 (Sat)

Questions attempted: 10642 - 10650
Questions solved:
10642
10646
10648
10649
10650

Only Zirui, Melvin and myself + the IOI people attended, so there was only 3 teams (ACM + 2 IOI teams)

10650 was an individual question we did while waiting for the IOI people.
Everyone (including the IOI people) solved it.

10642 - TJB
10646 - MZKC
10648 - MZKC
10649 - WZR


Discussion:

10642 - Very simple maths problem. If you realise that all the diagonal paths share equations of the form x + y = c, then solution is trivial

10646 - Simulation problem, pretty trivial

10648 - Probability/combinatorics question. Instead of finding the required answer, find the probability of every box is filled, then take 1 - p.

10649 - Geometry question, the formulation of the answer is pretty easy, but I think precision is a major problem.

10650 - Prime number generation + checking. Again, trivial


Ideas for unsolved:

10643 - Possible DP + Brute force solution. DP for the nodes WITHOUT the root node and brute force to add in the root node
10644 - I think there is a DP formulation. I'll work on it and email you if I can find it. Otherwise, we agree that brute force may work.
10645 - DP solution.
10647 - Use DP to find the cost of putting the house in each interval, then use quadratic maths to determine actual position.



junbin


ps: Zirui, can you please send me your formulation for 10649? I tried many different formulas, all of them worked with every test example I have, but all gave WA :(


Wanna introduce to those C++ guys a technique to do faster string IO and, at the same time, to enjoy the power of STL.

For example, a typical C++ programmer may write:

#include <iostream>
#include <string>

int main() {
string s;
getline(cin, s);
cout << s << endl;
}

But he/she can do better this way:

#include <cstdio>
#include <string>

string readln() {
char c[2000];
gets(c);
return string(c);
}

int main() {
string s;
s = readln();
puts(s.c_str());
}

Two cent, two cent. :)
A word of caution: Though my method improves the IO speed, I don't recommend people who are not familiar with <stdio.h> to use it unless really necessary.

Mixing <stdio.h> and <iostream> results in unexpected runtime error or wrong answers. (I heard the reason is that one of them uses buffer, while the other does not.) This means you have to rely solely on either <stdio.h> or <iostream> for IO. But <stdio.h> is quite different from <iostream>; after making a change (from <iostream> to <stdio.h>), you might experience quite a period of WAs and frustration, like me now.
Hi,

I finally got some time to do 10638. As from the previous discussion, we need to find groups of people whose average is the same as the average of all the people (within 1 cent). Note that there're at most 10 people, so a simple brute force backtracking should do the job.

Note that during the recursion, we can only conclude that a group is 'closed' (i.e. no more people should be added) if that group's average is *exactly* the same as the average. If the average is within one cent's range, you'll fail tests like:

9.55 9.55 9.53

(if 9.55 is considered closed, then 9.53 can never be put in a group, which means you get no answer for this input)

Other than this i found everything else trivial. With a few pruning that seemed too nice and simple to miss, i got a runnig time of 0.01 sec (apparently melvin did a lot better though :P)

Btw, sorry i wasn't at sat's training. The french SEP people had to go out to buy travel insurance today :(



-----Original Message-----
From: Teng Junbin [mailto:tengjb@singnet.com.sg]
Sent: Sat 5/15/2004 7:20 PM
To: Zhou Junyu; Cai Junfu; Guo Yunsong; Junjie Liang; Kah Keng Tay; Li Mengran; Liu Chang; Melvin Zhang; Sing Kiat Oh; Stephanus; Steven Halim; Wang Zirui; You Quan Chong; Leung Ngai-Hang Zachary
Cc:
Subject: Training on 15 May 04 (Sat)

Questions attempted: 10642 - 10650
Questions solved:
10642
10646
10648
10649
10650

Only Zirui, Melvin and myself + the IOI people attended, so there was only 3 teams (ACM + 2 IOI teams)

10650 was an individual question we did while waiting for the IOI people.
Everyone (including the IOI people) solved it.

10642 - TJB
10646 - MZKC
10648 - MZKC
10649 - WZR


Discussion:

10642 - Very simple maths problem. If you realise that all the diagonal paths share equations of the form x + y = c, then solution is trivial

10646 - Simulation problem, pretty trivial

10648 - Probability/combinatorics question. Instead of finding the required answer, find the probability of every box is filled, then take 1 - p.

10649 - Geometry question, the formulation of the answer is pretty easy, but I think precision is a major problem.

10650 - Prime number generation + checking. Again, trivial


Ideas for unsolved:

10643 - Possible DP + Brute force solution. DP for the nodes WITHOUT the root node and brute force to add in the root node
10644 - I think there is a DP formulation. I'll work on it and email you if I can find it. Otherwise, we agree that brute force may work.
10645 - DP solution.
10647 - Use DP to find the cost of putting the house in each interval, then use quadratic maths to determine actual position.



junbin


ps: Zirui, can you please send me your formulation for 10649? I tried many different formulas, all of them worked with every test example I have, but all gave WA :(


 

10645 Floor Tiling can be solved using DP.
 
Step 1:
Determine which are the basic rectangular shapes that the L-shape bits can form
 
Step 2:
Combine the basic rectangles into composite rectangles (DP)
 
Step 3:
Using DP, count the number of rectangles that can be formed with at MOST length L, width W
 
Step 4:
Find answer
 
 
 
Hints:
Step 1:
2x3, 3x2, 5x9, 9x5  (5x9/9x5 are very complicated, I didn't know about them until I read the forum :)
 
Step 2:
f( w, h ) == 1  => a rectangle of width w and height h can be formed using the L-shapes
if f( w, h ) = 1, then what can we say about rectangles slightly larger?
 
Step 3:
Very simple counting DP.
 
Step 4:
Draw out the table obtained in step 3 and then mark the boundaries of l1, l2, w1, w2 and try to find a formula.
Note: l1 may not be > l2, same for w1, w2.  Also, l1/l2, w1/2 have no MINIMUM bound.
 
 
 
 
junbin
Questions attempted: 10642 - 10650
Questions solved:
10642
10646
10648
10649
10650
 
Only Zirui, Melvin and myself + the IOI people attended, so there was only 3 teams (ACM + 2 IOI teams)
 
10650 was an individual question we did while waiting for the IOI people.  Everyone (including the IOI people) solved it.
 
10642 - TJB
10646 - MZKC
10648 - MZKC
10649 - WZR
 
 
Discussion:
 
10642 - Very simple maths problem.  If you realise that all the diagonal paths share equations of the form x + y = c, then solution is trivial
 
10646 - Simulation problem, pretty trivial
 
10648 - Probability/combinatorics question.  Instead of finding the required answer, find the probability of every box is filled, then take 1 - p.
 
10649 - Geometry question, the formulation of the answer is pretty easy, but I think precision is a major problem.
 
10650 - Prime number generation + checking.  Again, trivial
 
 
Ideas for unsolved:
 
10643 - Possible DP + Brute force solution.  DP for the nodes WITHOUT the root node and brute force to add in the root node
10644 - I think there is a DP formulation.  I'll work on it and email you if I can find it.  Otherwise, we agree that brute force may work.
10645 - DP solution.
10647 - Use DP to find the cost of putting the house in each interval, then use quadratic maths to determine actual position.
 
 
 
junbin
 
 
ps:  Zirui, can you please send me your formulation for 10649?  I tried many different formulas, all of them worked with every test example I have, but all gave WA :(
The questions attempted are:  10637 - 10641
 
Questions solved are:
 
10637:  (Melvin, Liu Chang, Junbin)
10638:  (Melvin)
 
 
10637:
 
Simple brute force: 9.895s   (TJB)
Brute force with basic pruning: 1.4s  (MZKC, LC, TJB)
Brute force with more pruning:  0.193 (TJB)
 
yes, I sent in a lot of submissions for this question.
 
 
 
10638:
 
Accepted method was based on greedy (refer to Melvin for more details).  The solution was proven to be wrong during discussion, but the UVA test data was poor and did not detect it.
 
After discussion, we agreed that some form of brute force is requried.  Details, refer to UVA forums.
 
 
 
 
 
 
junbin

To deduce whether it's day or night, we only need to examine all the possible valid (race of A, race of B, race of C, race of D, race of E, day/night) tuples. If all these tuples agree that it's day / night, then we have a conclusion. This is exactly the same as the races of A-E, no special handling is required.

Even if there's no human, we possibly can deduce whether it's day or night. E.g. if we are sure that B is lying, and B said it's day, then it must be night.

Liu Chang

-----Original Message-----
From: Stephanus
Sent: 11/5/2004 (星期二) PM 6:49
To: Wang Zirui; Liu Chang; 'Teng Junbin'; 'Zhou Junyu'; 'Guo Yunsong'; Li Mengran; 'Melvin Zhang'; 'Steven Halim'; Leung Ngai-Hang Zachary
Cc:
Subject: Help 592



Hi all,
I want to ask about 592 : Island of Logic, in problem statement (OUTPUT)
...it may be stated whether it is day or night...
does this mean that we may/may not state this?

can we deduce it is night/day if the none of the speakers are human?
if yes,can you give me example?

In sample I/O
3
A: B is human.
B: A is evil.
A: B is evil.

Conversation #4
A is evil.
B is divine.

[My comment:There's no human, so we don't have to state it is day/night]

Do we have to consider only those who are speaking?

What's the answer for these test cases? Can you explain?

6
A: B is human.
A: B is evil.
B: A is human.
C: A is not lying.
B: C is not human.
D: E is not lying.

[My ans/comment]
No facts are deducible
Because we don't know about D and E?

3
A: I am human.
B: I am human.
A: B is lying.

[My ans/comment]
No facts are deducible

7
A: It is night.
B: It is day.
C: I am human.
E: C is human.
C: E is divine.
A: B is lying.
B: C is evil.

[My ans/comment]
No facts are deducible.

Do you have any other test cases?

Thanx in advance.

regards,
stephanus

Hi everyone,

Today we tried to solve 592 - Island of Logic <http://acm.uva.es/cgi-bin/OnlineJudge?Volume:5>. It's a logic programming question. It's a new type of problem for most of us, I guess, and there are new techniques to learn.

The basic method is exhaustive searching, enumerating all possibilities.
But turning the search result into output needs some thought--you might ask questions like "What does inconsistency in the results mean?"

I made a mistake in spelling, taking "devine" for "divine," but I believe you guys won't make this sort of error.

Regards,
Zirui
 

hi,
 
  10623
    our approach is pure mathematical. the no. of area generated is equal to the no. of intersection + 2.
 
    m elipses have : 2 + 2m(m-1) intesections
    n circles have : 2 + n(n-1) intersections
    p triangles have :   2 + 3p(p-1) intersections
   
    m elipses over n circles : 4mn
    p triangles over m elipses(circles) gives 6pm(6pn)
   
    so total no. of area is :
 
    2 + 2m(m-1) + n(n-1) + 3p(p-1) + 4mn + 6p(m+n)
 
    the only problem now is it involves n(n-1) which is quadratic. Since n < 20000, the determinant of this function might involve big number. So we have to code big number square root function. ^_^
 
 
  10627
        again, we use mathematical approach.
 
         we calculate no. of headon meet and no. of catchup meet, then minus the double count(means they meet at the end point). however, though the approach is very clear cut, we continue to get wrong answer from online judge. hehe. dont know where the bug is.
 
 
    please advise.
 
 
 
junfu
 
----- Original Message -----
From: Teng Junbin
Sent: Wednesday, May 05, 2004 4:36 PM
Subject: Summary for today's training (Wed 5 May)

 
The questions attempted: 10623 - 10627
 
Questions solved:
 
10625 (GNU = GNU'sNotUnix)  :  Everyone.  Method: Brute force
10624 (Super Number)  :  Liu Chang.  Method: Brute force
10626 (Buying Coke)   :   Stephanus, Junbon.  Method:  Brute force, DP
 
Anything wrong with that, please notify me and Yunsong (I think he is keeping score).
 
About 10625:
 
Standard brute force generation/emulation.  Takes around 0.5s  + or - 0.5s
 
 
About 10624:
 
Brute force generation using modulo arithmetic.  Exact details check with Liu Chang.
 
 
About 10626:
 
I think the O(1) method given in the forum may be wrong.. I can't prove it, but it just feels wrong somehow..
 
DP method (with slight brute force type pruning) took 0.7s
Brute force (I think Stephanus used standard brute force pruning techniques as well)  took 0.5s
 
 
About 10623/10627:
 
I think Junfu and Liu Chang were working on a mathematical approach to these questions, but couldn't finished before 1.30pm.  If anyone finds the answer, please share.
 
 
junbin
 
ps: Starting from the 1st training AFTER the release of the results, the CS1102 top students may be joining us.

Nice work on the summary Junbin, I think we should have a roster for this, a different person write a short summary every training session. I managed to do the buying coke question after finally realising I was missing one of the ways to buy a coke which is 1x10 + 3x1 = 1x8 + 1x5 and a hint on reducing the size of the DP from Junbin.

See ya all on Saturday.GNU = GNU Not Unix
Emulation, I think everybody got this

Super Number
Like junbin said, Brute force generation using modulo arithmetic. Exact details check with Liu Chang/Mengran =)

Buying Coke
I don't use any pruning actually, well only one. The difference is how you do brute force and what do you brute force.

Notice to get 8, there are only a few ways (minus means get exchange)
1. 8 = 10 - 1 - 1 (insert 1 coin)
2. 8 = 10 + 1 + 1 + 1 - 5 (insert 4 coin)
3. 8 = 5 + 5 - 1 - 1 (insert 2 coin)
4. 8 = 5 + 1 + 1 + 1 (insert 4 coin)
5. 8 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 (insert 8 coin)

Denote xi, number of times we do the i-th operation, then total coin needed = x1 * 1 + x2 * 4 + x3 * 2 + x4 * 4 + x5 * 8 and x1 + x2 + x3 + x4 + x5 = C (C = number of Coke)

another thing to notice is that we don't have to care about 1 if the input is valid

just brute force :
for x1 = 0 to possible number of n10
for x2 = 0 to possible number of n10 - x1 (notice we get 5 for exchange)
for x3 = 0 to possible number of n5'/2 (n5' = n5 + x2)
for x4 = 0 to possible number of n5' - x3 for x5 we can get easily by above equation,
x5 = C - x1 - x2 - x3 - x4
compute total coin needed
keep track the minimum
output the minimum

maybe you can do further pruning, but doing this is enough

regards,
stephanus
Hi,

Junfu and I juz got 10627 Infinite Race working. The problem was that we used 32-bit ints instead of 64-bits. The method was fine. Juz to restate wat junfu said earlier, we have to calculate three numbers:
1. the number of head-on meets, which occurs when the total distance travelled by A and B is an odd multiple of L 2. the number of overtakes, which occurs when the difference in the distances travelled by A and B is an odd multiple of L 3. the number of double counted cases, which occurs when both A and B have travelled odd multiples of L (simultaneously)

The juz take (1) + (2) - (3). It's a simple O(1), but be careful with all your +1s and -1s.

Liu Chang