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:
#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 */
};