Top Coder SRM 614 DIV 2

来源:互联网 发布:c51单片机计算器 编辑:程序博客网 时间:2024/06/09 08:57

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, y< 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 0x7fffffffclass 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 */};






0 0
原创粉丝点击