您的位置:首页 > 运维架构

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 */
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: