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

Topcoder SRM 636 Div1 B

2016-06-03 16:44 1026 查看
题意:给你一个矩阵,矩阵中有’.’和’#’,’.’表示空闲的地方,’#’表示非空闲的地方,现在有r个机器人,在空闲的地方等概率的选择一个空闲的地方。现在定义他们之间的关系,对于一个机器人,他和距离他最近的机器人有一条边,如果距离相等,那么选择列坐标小的,如果还相等,选择行坐标小的。所谓的距离为他们之间的欧几里得距离。对于选定位置的机器人,会形成r条边r个点的有向图,那么问在这些可能形成的图中连通分量的期望是多少。

思路:我们如果仔细的想想的话,会发现在图中的连通分量的特点,就是连通分量的点数为2(想想为什么?),那么如果我们是不是可以处理出连通分量出现的总的组合数,再去求连通分量的期望就会简单。

#include <bits/stdc++.h>

using namespace std;

struct node
{
double x,y;

node(){}

node(double _x,double _y):x(_x),y(_y){}

double operator - (const node &a)const
{
return (x-a.x)*(x-a.x)+(y-a.y)*(y-a.y);
}
}S[410];

class ClosestRabbit
{
public :

long double c[410][410];

int n;

void Init()//计算组合数
{
memset(c,0,sizeof(c));

c[0][0] = 1;

for(int i = 1;i<=400;i++)
{
c[i][0] = 1;

for(int j = 1;j<=i;j++)
{
c[i][j] = c[i-1][j]+c[i-1][j-1];
}
}
}

int Judge(int a,int b,int c)//判断a与b,c中的谁相连。
{
if(S[a]-S[b] != S[a]-S[c])
{
return S[a]-S[b]<S[a]-S[c]?b:c;
}
if(S[b].x != S[c].x) return S[b].x<S[c].x?b:c;

return S[b].y<S[c].y?b:c;
}

double getExpected(vector <string> board, int r)
{
n = 0; Init();

int sn = board.size();

int sm = board[0].size();

for(int i = 0;i<sn;i++)
{
for(int j =0 ;j<sm;j++)
{
if(board[i][j] == '.')//记录空闲的位置
{
S
.x = i;

S[n++].y = j;
}
}
}

long double  res = 0;
// 由于连通分量只有两个点,那么我们可以枚举点,来判断是不是能组成连通分量。
for(int i = 0;i<n;i++)
{
for(int j = i+1;j<n;j++)
{
int ans = 0;

for(int k = 0;k<n;k++)
{
if(k != i && k != j && Judge(i,j,k) == j && Judge(j,i,k) == i)
{
ans++;
}
}

if(ans>=r-2)//表示能够组成连通分量,那么我们就从符合条件的点中选出r-2个来构成图,方案数就是对应连通分量出现的次数。
{
res += c[ans][r-2];
}
}
}

return  res/c
[r]; //计算期望
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: