Monday, November 27, 2006 Match summaryIn total there were 278 submissions for HS SRM 21 by 148 members. Continuing his impressive performance, Zuza enjoyed another HS SRM win with 1708.72 points. He was followed by fatit, who has just turned red, with 1649.62 points after the system test. Burunduk3also did an excellent job with 1596.72 points. After the system test refused a few submissions, 27 members ended up passing all three problems successfully.This set of problems was reasonably easy, and the high number of submissions made this set especially exciting. Congratulations to the great number of gifted high schoolers from all over the world who performed better than they have before. PostOffice Used as: Division One  Level One: This problem was the easiest one, with 129 members' solutions passing the system tests. Two tasks should be accomplished here: 1. Remove all the spaces from both addresses. 2. Perform a caseinsensitive string comparison. If two strings are equal, simply return 1. Otherwise, return the leftmost 0based position at which they differ. Pay attention, though  one tricky case is that either parameter can be an empty string here. Here is tomekkulczynski's code: char down(char x) { if(x>='A' && x<='Z') return x'A'+'a'; return x; } int matchAddress(string a, string b) { string A,B; int i; for(i=0; i<a.size(); i++) if(a[i] != ' ') A+=down(a[i]); for(i=0; i<b.size(); i++) if(b[i] != ' ') B+=down(b[i]); if(A == B) return 1; for(i=0; A[i]==B[i]; i++); return i; } FixedPoint Used as: Division One  Level Two: A fixed point is a point that does not change upon application of a map, system of differential equations, etc. One of the oldest fixedpoint theorems  Brouwer's  was developed in 1910. By 1928, John von Neumann was using it to prove the existence of a "minimax" solution to twoagent games (which translates itself mathematically into the existence of a saddlepoint). For this problem, you are not required to know much about such fixed point theorem, but only to solve the following set of equations: (scale * cos(rotate)  1) * x  scale * sin(rotate) * y = translate[0] * cos(rotate) + translate[1] * sin(rotate) scale * sin(rotate) * x + (scale * cos(rotate)  1) * y = translate[0] * sin(rotate)  translate[1] * cos(rotate) Step 1: To get a clear view, we define four new variables a A, B, C and D. A = (scale * cos(rotate)  1) B = scale * sin(rotate) C = translate[0] * cos(rotate) + translate[1] * sin(rotate) D = translate[0] * sin(rotate)  translate[1] * cos(rotate) Step 2: These two equations are becoming: A * x  B * y = C (1) B * x + A * y = D (2) Step 3: To calculate the answer of x, we do: (1) * A: A * A * x  A * B * y = A * C (2) * B: B * B * x + A * B * y = B * D Step 4: Equation(1)'s left side + Equation(2)'s left side = Equation(1)'s right side + Equation(2)'s right side A * A * x + B * B * x = A * C + B * D Step 5: x = ( A * C + B * D ) / ( A * A + B * B ) The sample method can be applied to calculate the answer of y: (1) * B : A * B * x  B * B * y = B * C (2) * A : A * B * x + A * A * y = A * D (2) * A  (1) * B A * A * y + B * B * y = A * D  B * C y = ( A * D  B * C ) / ( A * A + B * B ) Here is my code: double A = (scale * cos(rotate)  1); double B = scale * sin(rotate); double C = translate[0] * cos(rotate) + translate[1] * sin(rotate); double D = translate[0] * sin(rotate)  translate[1] * cos(rotate); vector <double> ans; ans.push_back(( A * C + B * D ) / ( A * A + B * B )); ans.push_back(( A * D  B * C ) / ( A * A + B * B )); return ans; ElectiveSystem Used as: Division One  Level Three:
This is a normal Dynamic Programming problem. We define S[i] as the sum of goodness
for the first i time units. dp[i][j] means the maximum value for the first i time
unites if we log in j times within it, but with a limit of D time units for each login.
n = 0; for (int i = 0;i < s.size();i ++) for (int j = 0;j < s[i].length();j ++) { n ++; a[n] = s[i][j]  'a' + 1; } memset(S , 0 , sizeof(S)); for (int i = 1;i <= n;i ++) S[i] = S[i  1] + a[i]; memset(dp , 0 , sizeof(dp)); int ret = 0; for (int i = 1;i <= n;i ++) for (int j = 1;j <= K;j ++) { int t = i  D; if (t < 0) t = 0; dp[i][j] = max(dp[i][j] , dp[t][j  1] + S[i]  S[t]); dp[i][j] = max(dp[i][j] , dp[i  1][j]); ret = max(ret , dp[i][j]); } return ret; 
