To my surprise it came out that my program should exceed the time limit as system logarithm is very, very slow - much slower than couting a power in linear time. I changed a few things and now everything is OK.
BTW: it's a bit strange that all the posts in this thread are mine, itn't is?
I am trying to solve problem 107 in Java, but the online judge kepps on giving me time limit exceeded. Could someone help please? Below is my code:
[java]import java.io.*;
import java.util.*;
class Main {
static String ReadLn (int maxLg)
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null);
return (new String (lin, 0, lg));
}
public static void main(String[] args) throws IOException {
String line;
while((line = ReadLn(255)) != null) {
StringTokenizer st = new StringTokenizer(line);
int height = Integer.parseInt(st.nextToken());
int num = Integer.parseInt(st.nextToken());
//We have a pair of simultaneous eqns -
//height / ((N + 1) ^ m) = 1 - eqn 1
//N ^ m = num - eqn 2
//Imagine a full m-ary tree and at level m,
//we have 'num' children.
//Take log on both sides for both eqns -
//rearranging, we get -
//m * log (N + 1) = log(height) - eqn 3
//m * log N = log(num) - eqn 4
//eqn 3 / eqn4 - we can solve for N -
//log(N + 1) = (log(height) / log(num)) * log N
//by trial and error
//with the value of N, we can solve for m using
//either eqn 3 or eqn 4
if ((height > 0) && (num > 0)) {
if ((height > 1) && (num > 1)) {
int test = 2;
boolean found = false;
double value = Math.log(height) / Math.log(num);
while(!found) {
if (test + 1 - Math.pow(test,value) < 1E-15)
found = true;
else test++;
}
int temp = 1;
int total = 1;
int total_height = 0;
int h = 1;
I have found inputs which my program takes very long to process - very large integers within the range of int - For example 100000000 99999999. I believe the bottleneck is in the while loop getting the root. Could anyone who have solved this problem suggest a more efficient way other than to get the root by brute force? Thanks.
I did include as a special case, height=1,workers=x, but it only seems logical to me that x=1 is the only valid input. (of course I checked that value on my code without the special case and it broke it).
But with these assumptions it is possible to get an accepted solution.
i am Time Limit too.
But my code run fast...
why?[cpp]
#include <stdio.h>
#include <math.h>
int alpha,N,height,rest_c,a,b;
int finished;
int ans1;
double ans2;
int i;
void main(void)
{
while (1)
{
scanf("%d",&height);
scanf("%d",&rest_c);
if (height==0 && rest_c==0)
break;
if (height==1)
{
printf("0 %d\n",rest_c);
continue;
}
if (rest_c==0)
{
printf("0 0\n");
continue;
}
finished=0;
for (N=1;N<9999999;N++)
{
for (alpha=1;alpha<9999999;alpha++)
{
a=(int)pow((int)N,(int)alpha);
b=(int)pow((int)N+1,(int)alpha);
if (b>height || a>rest_c)
break;
if (a==rest_c && b==height)
{
finished=1;
break;
}
}
if (finished==1)
break;
}
ans1=1;
for (i=1;i<alpha;i++)
{
ans1+=(int)pow(N,i);
}
ans2=0;
for (i=0;i<=alpha;i++)
{
ans2+=(float)pow(N/(double)(N+1),i);
}
ans2*=height;
Why the code not break the loop while the test code 216 125
I don't understand, hope somebody help me.
PS> here is not the full code just the sample.
[cpp]#include <iostream.h>
#include <math.h>
void main()
{
while(1)
{
int height,cats; // height means height of initial cat
// cats means the number of worker cats
// pow(n+1,a)=216
// pow(n,a)=125
cin>>height>>cats;
if(height==0&&cats==0) break;
int a=1;
long double m,n;
while((m-n)!=1)
{
m=exp(log(height)/a);
n=exp(log(cats)/a);
//cout<<m-n<<endl;
//if(m==1+n) break; // ??? maybe wrong in some cases
a++;
}
/*int notwork=0; // the number of cats that not work
int sum=0; // height of the stack of cats
int N=1;
a++;
while(a--)
{
if(a) notwork+=N;
sum+=N*(int)height;
N*=(m-1); // why (int)m=6 (int)n=4???
height/=m;
}
cout<<notwork<<" "<<sum<<endl;*/
}
}[/cpp]
The best method is to form two equations with two unknowns; ( N,x)
where N has its defined meaning x is related to the number of different types of cats( cats of various heights).
Use the two equations to solve for N and then find the value of x.
Good Luck.
[cpp]
// @JUDGE_ID: 33444KK 107 C++
//
// 107_CatInTheHat: Determine which cats are not working, and the height of all cats
//
#include <cstdio>
#include <cmath>
// The base types
typedef char int8;
typedef short int16;
typedef long int32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
// The maximum amount of layers to be checked
#define MAX_LAYERS 32
//------------------------------------------------------------------------------------// F U N C T I O N S
//------------------------------------------------------------------------------------
// This function determines whether 2 doubles are (approximately) equal
bool AreEqual(double dA, double dB, double dEpsilon) { return (dA > dB - dEpsilon) && (dA < dB + dEpsilon); }
// This function is the entrance of the app
int main()
{
uint32 u32HeightBiggestCat, u32TotSmallestCats;
// Get the next input parameters
while((scanf("%d %d", &u32HeightBiggestCat, &u32TotSmallestCats) == 2) && u32HeightBiggestCat > 0)
{
// Do we have the special case that the biggest cat is of height 1?
if(u32HeightBiggestCat == 1) printf("0 %u\n", u32TotSmallestCats);
else
{
uint8 u8TotLayers = 0;
uint32 u32CatsPerHat, u32TotNonWorkerCats, u32TotHeightAllCats;
// Set the initial state
u32CatsPerHat = u32TotSmallestCats;
// Find a combination for which it holds that : (CatsPerHat+1)^TotLayers == HeightBiggestCat
// where CatsPerHat and TotLayers are whole numbers
do
{
double dCatsPerHat;
// Find a combination for which it holds that : CatsPerHat^TotLayers == TotSmallestCats
// where CatsPerHat and TotLayers are whole numbers
do
{
// Get the amount of smallest cats (N^L)
u8TotLayers++;
dCatsPerHat = pow((double)u32TotSmallestCats, 1.0 / (double)u8TotLayers);
u32CatsPerHat = (uint32)dCatsPerHat;
}while(u8TotLayers <= MAX_LAYERS && !AreEqual(dCatsPerHat, (double)u32CatsPerHat, 0.0001));
// Calculate the total number of non-worker cats and the sum of the heights of all the cats
u32TotNonWorkerCats = 1;
u32TotHeightAllCats = u32HeightBiggestCat;
for(uint8 u8Layer=1;u8Layer<=u8TotLayers;u8Layer++)
{
uint32 u32CatsOnThisLayer, u32HeightPerCat;
// Add the number of cats on this layer to the total
u32CatsOnThisLayer = (uint32)pow((double)u32CatsPerHat, (double)u8Layer);
u32TotNonWorkerCats += u32CatsOnThisLayer;
// Add the height of each cat on this layer to the total
u32HeightPerCat = (uint32)pow(double(u32CatsPerHat+1), double(u8TotLayers-u8Layer));
u32TotHeightAllCats += u32HeightPerCat * u32CatsOnThisLayer;
}
// Exclude the worker cats
u32TotNonWorkerCats -= u32TotSmallestCats;
// Show the result
printf("%u %u\n", u32TotNonWorkerCats, u32TotHeightAllCats);
}
}
216 125 results in 31 671 for my code!
To make sure nothing went wrong when copy'n'pasting
my code to this forum I copied it back and recompiled it.
I use Visual Studio.NET 2003 as compiler. What do you use?
The numbers mentioned above the code are really what
I get when running my app.
Does any one see an error with the input / output, or
maybe knows an input which is 'sneaky'?
El-idioto wrote:
I use Visual Studio.NET 2003 as compiler. What do you use?
I compiled your program with the gcc (g++) compiler v. 3.2.1 under Linux. It gives the same result that you reported for your other test cases, but not for this one.