The wondering mind of Mark, the Great and Powerful

Mark Gordon's Blog at vbCity

This blog hosted by:
http://blogs.vbcity.com      
  Home :: Syndication  :: Login

AprMay 2008Jun
SMTWTFS
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Archives

Topics

Ok, so I think I'm going to start using this blog to discuss TopCoder Competitions.  Single Round Match 295, which was on Wednesday, was pretty fun, although I'm a little disappointed that I only got the first problem.  My rating went up nonetheless.

So, you can view the first problem here, (you have to be logged in, sorry) basically the idea was that you were trying to build a bridge of D length with cards of L length and you had to return the amount of cards necessary to complete it.  It had some stuff about equilibriums and center of masses... but the pictures they provided made it clear that each card added 1/(2n) units to the bridge where n is the card number.  So all you had to do was sum 1/(2n) until it was greater than D/L (lol)

class BuildBridge
{
public:
int howManyCards(int D, int L)
{
   
int i;
   
double dist = 0.0;
   
for (i = 2; L * dist < D - 1e-9; i+=2)
    {
       
dist += 1.0 / (double)i;
    }
   
return i / 2 - 1;
}
};

Unfortunately, I misread the 500 point question.  You can view it here.  You had to assist thief “Jimmy Lightning” steal the greatest value of diamonds.  You were given a list of diamonds that each had a value, the amount of time it took to steal, and the room it was located in.  Jimmy instantly moves from one room to another.  To make things complicated, each door closes at a certain time after the robbery begins.  Rooms are connected linearly, so you need to go through room 3 to go from room 2 to room 4 (I missed this part).  Also, you must leave through door 1.

One of the rules on TopCoder is that your algorithm must complete in 2 seconds.  That means you just can't brute force this with a recursive method.  I attacked this problem by realizing that at any time t, after the robbery began there is only one way to get the greatest value of diamonds.  So at any time t you should try to steal every type of diamond that you can with the room being accessible after you steal it, and recursively call the same function at t + the time it takes to steal that diamond.  After the highest value has been obtained from those returned values, simply store that number to a cache, and if later is your function is called at that same value of t you already have the answer.  (Note I got this wrong during the competition but I fixed it after)

class JimmyLightning
{
public:
vector <int> doors;
vector <int> dv;
vector <int> dt;
vector <int> dr;
vector <int> maxdoor;
vector <int> cache;

int robTheBank(vector <int> d, vector <string> diamonds)
{
   
doors = d;
   
for (int i = 0; i < diamonds.size(); i++)
    {
       
int v, t, r;
       
stringstream ss;
       
ss << diamonds[i];
       
ss >> v >> t >> r;
       
dv.push_back(v);
       
dt.push_back(t);
       
dr.push_back(r);
    }
   
int i = 0;
   
do
   
{
       
int md = -1;
       
for (; md < (int)doors.size() - 1; md++)
        {
           
if (i >= doors[md + 1])
               
break;
        }
       
maxdoor.push_back(md);
       
cache.push_back(-1);
    }
while (maxdoor[i++] != -1);
   
solve(0);
   
return cache[0];
}
void solve(int t)
{
   
if (cache[t] != -1)
    return;
   
    vector <int> res;
   
for (int i = 0; i < dv.size(); i++)
    {
       
if (t + dt[i] < maxdoor.size())
           
if (dr[i] - 1 <= maxdoor[t + dt[i]])
            {
               
solve(t + dt[i]);
               
res.push_back(cache[t + dt[i]] + dv[i]);
            }
    }
   
int max = 0;
   
for (int i = 0; i < res.size(); i++)
       
if (res[i] > max)
           
max = res[i];
   
cache[t] = max;
}
};

The third problem was sort of a downer.  You can view it here.  I didn't get this problem and I still haven't been able to get it to work.  I had to read the analysis of this problem after it was posted to figure out how you were supposed to do it.  This problem statement is pretty long so I'll leave out a summary of it.

This problem was supposed to be done by a simple simulation.  Obviously you can get into an infinite loop of “W“s that would cause a problem.  Another rule of top coder is that when you are returning double values you can be off by (absolutely or relatively) 1e-9.  So the idea in this problem was just to simulate the problem until the results of the function call become so insignificant (by running into a lot of “W”s) that you don't have to go any further in the simulation.  I tried to implement this idea but I couldn't get it working on all of the test cases.

posted on Friday, March 31, 2006 5:52 PM