TopCoder SRM 431 DIV 2
Problem | Check | Points |
250 | ○ | 241.69 |
500 | × | - |
1000 | - | - |
500は問題文の「previously」に泣かされた・・・
Problem 250 MegaCoolNumbersEasy
問題
A positive integer is called a mega cool number if its digits form an arithmetic progression. An arithmetic progression is a sequence of numbers in which the difference between any two consecutive numbers is the same. Return the number of mega cool numbers between 1 and N, inclusive.
http://www.topcoder.com/stat?c=problem_statement&pm=10281&rd=13522
My code
// vが階差数列かどうかを判定する。 bool isArithProg(deque<int> v){ int dif=v[1]-v[0]; for(int i=0 ; i<(signed)v.size()-1 ; i++){ if(v[i+1]-v[i] != dif) return false; } return true; } deque<int> integerDigits(int x){ deque<int> arr; while(x!=0){ arr.push_front(x%10); x/=10; } return arr; } bool isMegacool(int n){ if(n<100) return true; return isArithProg(integerDigits(n)); } class MegaCoolNumbersEasy { public: int count(int N) { int result=0; for(int i=1 ; i<=N ; i++){ if(isMegacool(i)) result++; } return result; } };
Problem 500 FallingPoints
問題
You are given a int X containing the x-coordinates of several points. Each point starts at an infinitely high y-coordinate. Starting with the first point, each point falls down until it is either a distance of R away from a previously fallen point or it reaches y = 0. Each point (after the first point) will start falling only when the previous one stops. Return a double, where the i-th element is the final y-coordinate of the i-th point.
http://www.topcoder.com/stat?c=problem_statement&pm=10261&rd=13522
解説
Let y[i] be the final y-coordinate for the i-th falling point. We can calculate y's in sequential order. For the first point, there is no previous point, so it just falls down, i.e. y[0] = 0. Assuming we know y[i-1], let's calculate y[i]. The i-th point falls along the line x = X[i]. So we need to find the highest y when the distance between the points (X[i], y) and (X[i-1], y[i-1]) is equal to R. We can write this in form of mathematical equation and do some simple transformations:
sqrt((X[i] - X[i-1])^2 + (y - y[i-1])^2) = R
(X[i] - X[i-1])^2 + (y - y[i-1])^2 = R^2
(y - y[i-1])^2 = R^2 - (X[i] - X[i-1])^2The last equation doesn't have solutions if R^2 - (X[i] - X[i-1])^2 < 0 or, equivalently, |X[i] - X[i-1]| > R (because the left part of the equation is always non-negative and the right part is negative). In this case i-th point will just fall down, i.e. y[i] = 0. Otherwise, we can take square root from both sides of the equation:
y - y[i-1] = +/-sqrt(R^2 - (X[i] - X[i-1])^2)
y = y[i-1] +/- sqrt(R^2 - (X[i] - X[i-1])^2)Since we would like to know the highest possible value of y, we can deduce that y[i] = y[i-1] + sqrt(R^2 - (X[i] - X[i-1])^2).
Java implementation follows.
public class FallingPoints { public double[] getHeights(int[] X, int R) { double[] y = new double[X.length]; y[0] = 0; for (int i=1; i < X.length; i++) if (Math.abs(X[i] - X[i-1]) > R) y[i] = 0; else y[i] = y[i-1] + Math.sqrt(R * R - (X[i] - X[i-1]) * (X[i] - X[i-1])); return y; } }http://www.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm431
My code
vector<double> result; vector<int> XX; double calc(int ii, double dist){ double a = 0, tmp; for(int i=ii-1 ; i<ii ; i++){ if(XX[ii]-XX[i] > dist) continue; tmp = sqrt(dist*dist - (XX[ii]-XX[i])*(XX[ii]-XX[i])) + result[i]; a = max(a, tmp); } return a; } class FallingPoints { public: vector <double> getHeights(vector <int> X, int R) { XX = X; result.clear(); result.push_back((double)0); for(int i=1 ; i<X.size() ; i++){ result.push_back(calc(i, (double)R)); } return result; } };
Problem 1000 SumAndProduct
問題
A list of non-negative numbers is called satisfactory if the sum of the numbers in the list is equal to S and the product of the numbers is equal to P. Find a satisfactory list with the least possible number of elements, and return its size. If no such list exists, return -1 instead. Please note that the list may contain non-integer numbers.
http://www.topcoder.com/stat?c=problem_statement&pm=10257&rd=13522
My code
class SumAndProduct { public: int smallestSet(int S, int P) { if(S==P) return 1; int n=2; double a; while(1){ if((double)S/(double)n<1){ n = -1; break; } a = pow((double)S/(double)n, (double)n); if(a >= P) break; n++; } return n; } };