Coder Profile - Show off your skills, get a coder profile.
 
 
 
code pin board CCC 2008 S5 Download Source Code
Author Details Code Information
divad12 ( David Hu )

Pinned 1 Codes
Posted 0 Coding Articles

Send A Message
View Coders Profile
Language C++
Expires Never
Length 3,178 Characters (88 Lines)
Password no password
Description

Here's my solution for S5, CCC 2008. It uses memoization to drastically enhance the performance of a recursive algorithm at the cost of memory. Unfortunately, I did this the weekend after the contest :(

Does a bottom-up, dynamic programming approach exist for this problem?
  1. // CCC 2008, Senior Contest, Problem 5: Nukit
  2. #include <iostream>
  3. #include <fstream>
  4. using namespace std;
  5.  
  6. // the 5 reactions that can be applied
  7. int rc[5][4] = { {2, 1, 0, 2}, {1, 1, 1, 1}, {0, 0, 2, 1}, {0, 3, 0, 0}, {1, 0, 0, 1} };
  8. // memoization tables. Requires about 230 kilobytes of memory
  9. bool hasCalculated[31][31][31][31];
  10. bool memoizedValue[31][31][31][31];
  11.  
  12. // Applies reaction to state. If the given reaction cannot be applied, it returns false.
  13. // It passes the array state by reference, and modifies its values.
  14. bool react(int (&state)[4], int reaction)
  15. {
  16.      for (int i = 0; i < 4; ++i)
  17.      {
  18.          if (state[i] < rc[reaction][i])
  19.              return false;
  20.          state[i] -= rc[reaction][i];
  21.      }
  22.      return true;
  23. }
  24.  
  25. // main recursive function that determines if state is a winning or losing state.
  26. // It returns true if state is a winning state or false if state is losing a losing state.
  27. bool isWinning(int state[4])
  28. {
  29.      // memoization: if the given state has already been calculated, simply
  30.      // return the memoized value
  31.      if (hasCalculated[state[0]][state[1]][state[2]][state[3]] == true)
  32.          return memoizedValue[state[0]][state[1]][state[2]][state[3]];
  33.  
  34.      // otherwise, calculate it:
  35.      int next[4];
  36.      for (int i = 0; i < 5; ++i)
  37.      {
  38.          // assign next to state
  39.          for (int j = 0; j < 4; ++j)
  40.              next[j] = state[j];
  41.  
  42.          // this is a winning state: there exists a losing state that can be reached
  43.          // from this state. Note that in C++ the first condition must be true in
  44.          // order for the second condition to be executed when using logical AND.
  45.          // Thus isWinning is terminable.
  46.          if (react(next, i) == true && isWinning(next) == false)
  47.          {
  48.              hasCalculated[state[0]][state[1]][state[2]][state[3]] = true;
  49.              memoizedValue[state[0]][state[1]][state[2]][state[3]] = true;
  50.              return true;
  51.          }
  52.      }
  53.  
  54.      // this is a losing state: either all states that can be reached from this
  55.      // state are winning states or no reactions can be applied to this state
  56.      hasCalculated[state[0]][state[1]][state[2]][state[3]] = true;
  57.      memoizedValue[state[0]][state[1]][state[2]][state[3]] = false;
  58.      return false;
  59. }
  60.  
  61. // MAIN PROGRAM EXECUTION
  62. int main()
  63. {
  64.      // File I/O declarations
  65.      ifstream fin ("s5.in");
  66.  
  67.      int lines;
  68.      fin >> lines;
  69.  
  70.      // initializes the hasCalculated array
  71.      for (int i = 0; i < 30; ++i)
  72.          for (int j = 0; j < 30; ++j)
  73.              for (int k = 0; k < 30; ++k)
  74.                  for (int l = 0; l < 30; ++l)
  75.                      hasCalculated[i][j][k][l] = false;
  76.  
  77.      int state[4];
  78.      for (int i = 0; i < lines; ++i)
  79.      {
  80.          fin >> state[0] >> state[1] >> state[2] >> state[3];
  81.          // if state is winning, then output Patrick. Otherwise, output Roland.
  82.          cout << ((isWinning(state) == true) ? "Patrick" : "Roland") << "\n";
  83.      }
  84.  
  85.      // waits for enter key
  86.      cin.get();
  87.      return 0;
  88. }
code pin board Back To Code Pin Board Post New Code
Please login to post comments.
 
VBAssassin     Posted 182 Days Ago
 
 
230Kb of memory... hardly an amount to be concerned about these days.
 
divad12     Posted 185 Days Ago
 
 
Not bad.

I got 45, but I was rushing and coded an incorrect algorithm for the 4th problem.
My program didn't check enough permutations because I completely overlooked
cases like 4/(1+1) (that is, the fact that division and subtraction are not
commutative).

Fortunately, I still have another year of high school to try again. :D
 
Cinjection     Posted 185 Days Ago
 
 
Pretty. I did 2008 CCC, but I didn't reach this question. I got 36/75. How did
you do?
Page 1 of 1
 
 
Part of the MyPingle Network
Development Blog :: Make A Donation :: Contact Me
Terms & Conditions :: Privacy Policy :: Documents
Version 1.44.00
Copyright © 2007 - 2008, Scott Thompson, All Rights Reserved