## Thursday, April 17, 2014

### Introduction

Cookie Clicker is a Javascript game by Orteil, where players click on a picture of a giant cookie. Clicking on the giant cookie gives them cookies. They can spend those cookies to buy buildings. Those buildings help them get even more cookies. Like this problem, the game is very cookie-focused. This problem has a similar idea, but it does not assume you have played Cookie Clicker. Please don't go play it now: it might be a long time before you come back.

### Problem

Once you have X cookies that you haven't spent on farms, you win! Figure out how long it will take you to win if you use the best possible strategy.

### Example

Suppose C=500.0, F=4.0 and X=2000.0. Here's how the best possible strategy plays out:
2. After 250 seconds, you will have C=500 cookies and can buy a farm that producesF=4 cookies per second.
6. Another farm will cost 500 cookies, which you can buy after 50 seconds.
8. Another farm would cost 500 cookies, but it actually makes sense not to buy it: instead you can just wait until you have X=2000 cookies, which takes about142.8571429 seconds.
Total time: 250 + 83.3333333 + 50 + 142.8571429 = 526.1904762 seconds.
Notice that you get cookies continuously: so 0.1 seconds after the game starts you'll have 0.2 cookies, and π seconds after the game starts you'll have 2π cookies.

### Input

The first line of the input gives the number of test cases, TT lines follow. Each line contains three space-separated real-valued numbers: CF and X, whose meanings are described earlier in the problem statement.
CF and X will each consist of at least 1 digit followed by 1 decimal point followed by from 1 to 5 digits. There will be no leading zeroes.

### Output

For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is the minimum number of seconds it takes before you can have X delicious cookies.
We recommend outputting y to 7 decimal places, but it is not required. y will be considered correct if it is close enough to the correct number: within an absolute or relative error of 10-6. See the FAQ for an explanation of what that means, and what formats of real numbers we accept.

1 ≤ T ≤ 100.

1 ≤ C ≤ 500.
1 ≤ F ≤ 4.
1 ≤ X ≤ 2000.

1 ≤ C ≤ 10000.
1 ≤ F ≤ 100.
1 ≤ X ≤ 100000.

### Sample

 Input Output ```4 30.0 1.0 2.0 30.0 2.0 100.0 30.50000 3.14159 1999.19990 500.0 4.0 2000.0 ``` ```Case #1: 1.0000000 Case #2: 39.1666667 Case #3: 63.9680013 Case #4: 526.1904762 ```
Solutions:
So I first solved it through a recursive function. (I still don't know why I did this stupid s***). So small-input file gave correct results but the program terminated during large-input evaluation (stack overflow error). :O

Here is the code (recursive):

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

static int i = 0;
static Vector<Double> vec;
static double target=0;
static double fRate = 0;
static double fCost = 0;

public static double fun(double prevFarmBuyTimes, double rate){
if(i==0){
}
rate+=fRate;
double WaitingTime = target/rate;
double projection = farmTime+WaitingTime;
i++;
if(vec.elementAt(i-1)>vec.elementAt(i)){
return fun(farmTime, rate);
}
else
{
return vec.elementAt(i-1);
}
}

public static void main(String[] args) throws Exception{
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\result.txt"));

int index = 1;
while(index<=ncases){

Pattern p = Pattern.compile("\\d+.\\d+");

if (m.find())
fCost = Double.parseDouble(m.group());

if (m.find())
fRate = Double.parseDouble(m.group());

if (m.find())
target = Double.parseDouble(m.group());

//LOGIC STARTS HERE
vec = new Vector<Double>();
i=0;
double time = fun(0,2);

bw.write("Case #"+index+": "+time);
bw.newLine();
bw.flush();
System.out.println(time);
index++;
}
}
}

And here is the improved version without recursion.(Gives correct results for large-inputs):

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public static void main(String[] args) throws Exception{
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\result.txt"));

int index = 1;
int i = 0;
Vector<Double> vec;
double target=0;
double fRate = 0;
double fCost = 0;

while(index<=ncases){

Pattern p = Pattern.compile("\\d+.\\d+");

if (m.find())
fCost = Double.parseDouble(m.group());

if (m.find())
fRate = Double.parseDouble(m.group());

if (m.find())
target = Double.parseDouble(m.group());

vec = new Vector<Double>();
i=0;

double rate =2;

double result = 0;

while(true){

rate+=fRate;
double WaitingTime = target/rate;
double projection = farmTime+WaitingTime;
i++;
if(vec.elementAt(i-1)<vec.elementAt(i)){
result =  vec.elementAt(i-1);
break;
}
}

System.out.println(result);
bw.write("Case #"+index+": "+result);
bw.newLine();
bw.flush();
index++;
}
}
}