Top Coder SRM 614 DIV 2
2014-06-07 13:51
363 查看
250:
没什么说的。<pre name="code" class="cpp">#include <sstream> using namespace std; class MicroStrings { public: MicroStrings(){} ~MicroStrings(){} string makeMicroString(int A, int D) { stringstream ss; while(A >= 0) { ss << A; A -= D; } return ss.str(); } /* data */ };
500:
求最少包含N-2个节点的正方形的最小面积,肯定尽量包含少的点让正方形的面积越小,因此只考虑包含N-2个点的正方形。数据量比较小,直接枚举不在正方形中的两个点,然后求包含剩下N-2个点的最小正方形。一个正方形由左下角的点以及它的边长确定。先确定左下角的点,找到N-2个点中最小的X----minX,最小的Y---minY。设左下角点坐标为(x1,y1),要使N-2个点都在正方形内部,必有x1< minX, y1 < minY。要使正方形面积最小,因此左下角的点坐标为(x1,y1)=(minX-1, minY-1)。然后确定边长,在N-2个点中最大的X为maxX,y方向最大的Y为maxY。要使正方形包含所有点,必有边长l>max(maxX - x1,maxY-y1),要使面积最小,因此去l = max(maxX - x1,maxY-y1) +
1。
#include <vector> #include <memory.h> #include <math.h> #include <iostream> using namespace std; #define inf 0x7fffffff class MinimumSquareEasy { public: MinimumSquareEasy(){} ~MinimumSquareEasy(){} long long minArea(vector <int> x, vector <int> y) { bool visit[60]; long long result = -1; for(unsigned int i = 0; i < x.size(); i++) { for(unsigned int j = i + 1; j < x.size(); j++) { memset(visit, 0, sizeof(visit)); visit[i] = visit[j] = 1; int minX = inf, maxX = -inf, minY = inf, maxY = -inf, x1, y1; long long l; for(unsigned int k = 0; k < x.size(); k++) { if(visit[k]) continue; if(x[k] < minX) minX = x[k]; if(x[k] > maxX) maxX = x[k]; if(y[k] < minY) minY = y[k]; if(y[k] > maxY) maxY = y[k]; } x1 = minX - 1; y1 = minY - 1; l = max(maxX - x1, maxY - y1) + 1; if(result == -1 || l * l < result) result = l * l; } } return result; } /* data */ };
1000:
由题意可知,在该人的第t步时,他所处的坐标是(t%N, t%M)。可以发现当t等于N、M的最小公倍数时,该人又回到了原点,并开始重复刚才的过程。令C等于lcm(N,M)。则该人所能到的状态由[0,C)确定。令E[X]表示该人首次到达X所用步数的期望,0<=X <=C,由于在每一步该人前进后退的概率都是1/2。因此容易得到E[X]=1/2(E[X-1] + 1) + 1/2(E[X + 1] + 1) =1/2(E[X-1] + E[X+1]) + 1 (0<X <C)
并且容易知道E[0] = E[C] = 0。即该人首次到原点的步数的期望是0,因为他初始位置就在原点。由上式容易得到
E[X]= 2E[X-1] - E[X-2] + 1 0<X<C (1)
发现这是一个递推的式子,我们的目标就是要把这个方程组解出来。注意到E[X]是由它之前的项线性表示的,因此我们用E[1]表示所有的E[X],即我们设E[X] = a[X]E[1] + b[X]。代入上式可以解出:
a[X]= 2a[X-1] - a[X-2]
b[X]= 2b[X-1] - b[X-2] - 2 2<X<C
且容易得到a[0] =0, a[1] = 1, b[0] = 0, b[1] = 0,然后由上述递推公式可以解出a[X], b[X]。 这样对任意X,
E[X] =a[X]E[1] + b[X] 0<=X < C (2)
现在唯一要做的便是求出E[1],就可以求出所有的E[X]了。对公式1应用累加法,容易得到
E[1]+ E[C-1] = 2(C-1) (3)
结合公式3和公式2,容易求出
E[1]= (2*C - 2 - b[C - 1]) / (a[C-1] + 1)
这样就可以求E[X]了。
<span style="font-family: Arial, Helvetica, sans-serif;">class TorusSailingEasy</span>
{ public: TorusSailingEasy(){} ~TorusSailingEasy(){} double expectedTime(int N, int M, int goalX, int goalY) { int cnt = N * M / gcd(N, M); int goal = -1; for(int i = 0; i < cnt; i++) { if((i % N == goalX) && (i % M == goalY)) goal = i; } if(goal == -1) return -1.0; a[0] = 0; a[1] = 1; b[0] = 0; b[1] = 0; for(int i = 2; i < cnt; i++) { a[i] = 2 * a[i - 1] - a[i - 2]; } for(int i = 2; i < cnt; i++) { b[i] = 2 * b[i - 1] - b[i - 2] - 2; } double E = (2 * cnt - 2 - b[cnt - 1]) / 1.0 / (a[cnt - 1] + 1); return a[goal] * E + b[goal]; } int gcd(int a, int b) { if(a < b) return gcd(b, a); if(b == 0) return a; return gcd(b, a % b); } private: int a[200], b[200]; /* data */ };
相关文章推荐
- TOPCODER/SRM 566 DIVII(250、500、1000题)(1000PT暂未附上代码)
- topcoder srm 518 div 2
- topcoder SRM495 div1 level3
- topcoder srm 519 div 1
- TopCoder SRM 681 Div. 2 Problem 500 - ExplodingRobots (枚举)
- TopCoder SRM 668 Div2 Problem 1000 - AnArray (数学)
- TopCoder SRM 140 Div2 第3题
- Topcoder SRM 656 DIV2 1000 题解(动态规划)
- Topcoder SRM 573 WolfPackDivTwo
- topcoder SRM div 2 level 1
- TopCoder SRM 659 Div2 Problem 500 - PublicTransit (思维)
- Topcoder SRM 652 DIV1 250
- TopCoder SRM 649 Div2 Problem 500 - CartInSupermarketEasy (区间DP)
- TopCoder SRM144 DIV1(one)
- Topcoder SRM 668 DIV 2
- topcoder srm 682 div1 -3
- [容斥] Topcoder SRM div1-3 12004. SetAndSet
- TopCoder Practice SRMs -- SRM 144 DIV 1 -- 300p
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
- Topcoder SRM 688 div2