Problem C. Theme Park - Qualification Round 2010 - Google Code Jam


Dashboard - Qualification Round 2010 - Google Code Jam

Problem

Roller coasters are so much fun! It seems like everybody who visits the theme park wants to ride the roller coaster. Some people go alone; other people go in groups, and don't want to board the roller coaster unless they can all go together. And everyone who rides the roller coaster wants to ride again. A ride costs 1 Euro per person; your job is to figure out how much money the roller coaster will make today.
The roller coaster can hold k people at once. People queue for it in groups. Groups board the roller coaster, one at a time, until there are no more groups left or there is no room for the next group; then the roller coaster goes, whether it's full or not. Once the ride is over, all of its passengers re-queue in the same order. The roller coaster will run R times in a day.
For example, suppose R=4, k=6, and there are four groups of people with sizes: 1, 4, 2, 1. The first time the roller coaster goes, the first two groups [1, 4] will ride, leaving an empty seat (the group of 2 won't fit, and the group of 1 can't go ahead of them). Then they'll go to the back of the queue, which now looks like 2, 1, 1, 4. The second time, the coaster will hold 4 people: [2, 1, 1]. Now the queue looks like 4, 2, 1, 1. The third time, it will hold 6 people: [4, 2]. Now the queue looks like [1, 1, 4, 2]. Finally, it will hold 6 people: [1, 1, 4]. The roller coaster has made a total of 21 Euros!

Input

The first line of the input gives the number of test cases, T. T test cases follow, with each test case consisting of two lines. The first line contains three space-separated integers: R, k and N. The second line contains N space-separated integers gi, each of which is the size of a group that wants to ride. g0 is the size of the first group, g1 is the size of the second group, etc.

Output

For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of Euros made by the roller coaster.

Official Analysishttps://code.google.com/codejam/contest/433101/dashboard#s=a&a=2
O(NR)  - At first glance, this problem appears to be a straightforward simulation: keep adding groups until you run out space on the roller coaster (or run out of groups), then re-form the queue and start again. Repeat this R times and you're done.

Optimization One

When you're sending the roller coaster out for 109 rides, you've got to expect that a few of them are going to be the same. If you store the queue of groups as an unchanging array, with a pointer to the front, then every time you send out a ride s, you could make a note of where it ended, given where it started. Then the next time you see a ride starting with the same group in the queue, you can do a quick lookup rather than iterating through all the groups.
That speeds up the algorithm by a factor of 103 in the worst case, leaving us with O(R) operations. There are some other ways of speeding up the calculation for any given roller coaster run: for example, you could make an array that makes it O(1) to calculate how many people are in the range [group_a, group_b] and then binary search to figure out how many groups get to go in O(log(N)) time. That gives a total of O(R log N) operations.

Optimization Two

As we observed in Optimization One, you're going to see a lot of repetition between rides. You're also going to see a lot of repetition between groups of rides. In the example in the problem statement, the queue was made up of groups of size [1, 4, 2, 1]. 6 people get to go at once. Let's look at how the queue changes between rides:
1, 4, 2, 1  [5]
2, 1, 1, 4  [4]
4, 2, 1, 1  [6]
1, 1, 4, 2  [6]
2, 1, 1, 4  [4]
4, 2, 1, 1  [6]
1, 1, 4, 2  [6]
As you may have noticed, there's a cycle of length three: starting from the second run, every third queue looks the same. We make 16 Euros when that happens, which means we'll be making 16 Euros every 3 runs until the roller coaster stops rolling.
So if the roller coaster is set to go 109 times: the first time it makes 5 Euros; then there are 999999999 runs left; and every three of those makes 16 Euros. 3 divides 999999999 evenly -- if it didn't, we'd have to do some extra work at the end -- so we make 5 + (999999999 / 3 * 16) = 5333333333 Euros in total.
It turns out that a cycle must show up within the first N+1 rides, because there are only Ndifferent states the queue can be in (after N, you have to start repeating). So you only have to simulate N rides, each of which takes O(N) time in the worst case, before finding the cycle: that's an O(N2) solution.

Optimization Three

Either of the optimizations above should be enough. But if you're a real speed demon, you can squeeze out a little more efficiency by combining the binary search that we mentioned briefly in Optimization One with the cycle detection from Optimization Two, bringing our running time down to O(N log N). An alternate optimization can bring us down to O(N); 
http://articles.leetcode.com/2010/05/problem-c-theme-park-solution.html
For the large input, the biggest R is 10^8 and the biggest N is 1000. Besides, there are at most 50 input set, which means the complexity is in the order of 10^12. Do you think this will run within minutes? (Hint: A solution that runs in minutes must be in the order of less than 10^9.)

1) We can use an array as the data structure. We do not have to move the contents of the array, as we can use an index which tells us where does the queue start. The index wraps around, which makes the array a circular array. This is much more efficient than using a queue.
2) We can exchange space for speed. Pre-processing comes to mind. At any index of the queue, we can know exactly where the next queue starts at. We can also be definite how many people will fit in the roller coaster for any starting index of queue. We store these two information in two tables. The pre-processing step has a complexity of O(N^2).
Using optimization 2) above, the complexity decreases to either O(N^2) or O(R), depend on which is bigger – N^2 or R.
We are almost done, however there is another trap. Note that each group’s number, gi could be as large as 10^7. There might be a case where you might add all gi, from i=1 to i=N, therefore the sum could be as large as 10^10, which is more than what a 32 bit integer could store. In short, just use 64 bit integer for the sum.
int n;
cin >> n;
for (int m = 0; m < n; m++) {
  long long R, k, N;
  cin >> R >> k >> N;
  long long li[2000];
  for (int i = 0; i < N; i++)
    cin >> li[i];
  long long result_money[2000] = {0};
  int result_st[2000] = {0};
  for (int h = 0; h < N; h++) {
    long long sum = 0;
    int st = h;
    bool done = false;
    for (int b = 0; b < N; b++) {
      if (sum + li[(h+b)%N] <= k) {
        sum += li[(h+b)%N];
        st = (st+1)%N;
      } else {
        result_money[h] = sum;
        result_st[h] = st;
        done = true;
        break;
      }
    }
    if (!done) {
      result_money[h] = sum;
      result_st[h] = st;
    }
  }
  long long money = 0;
  int st = 0;
  for (long long i = 0; i < R; i++) {
    money += result_money[st];
    st = result_st[st];
  }
  cout << "Case #" << m + 1 << ": " << money << endl;
}

Small: brute force.
public static void main(String args[]) throws Exception {
//String inFile = args[0];
//String inFile = "C-example.in";
String inFile = "C-small-attempt0.in";
//String inFile = "C-large.in";
String outFile = inFile + ".out";
LineNumberReader lin = new LineNumberReader(new InputStreamReader(new FileInputStream(inFile)));
PrintWriter out = new PrintWriter(new File(outFile));
int NCASE = Integer.parseInt(lin.readLine());
for(int CASE = 1; CASE <= NCASE; CASE++) {
out.print("Case #" + CASE + ": ");
String l = lin.readLine();
String ll[] = l.split(" ");
int R = Integer.parseInt(ll[0]);
int k = Integer.parseInt(ll[1]);
int N = Integer.parseInt(ll[2]);
int g[] = new int[N];
l = lin.readLine();
ll = l.split(" ");
for(int i = 0; i < N; i++)
g[i] = Integer.parseInt(ll[i]);
int sum[] = new int[N];
int nn[] = new int[N];
for(int i = 0; i < N; i++) {
int s = 0, j = 0, n;
do {
n = (i + j) % N;
int z = g[n];
if(s + z > k)
break;
s += z;
} while(++j < N);
sum[i] = s;
nn[i] = n;
}
long e = 0;
int n = 0;
for(int i = 0; i < R; i++) {
e += sum[n];
n = nn[n];
}
out.println(
e//y
);
}
lin.close();
out.close();
}
Read full article from Dashboard - Qualification Round 2010 - Google Code Jam

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts