using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("2");
WillReturn.Add("0 2");
//4.500000000
}
else if (InputPattern == "Input2") {
WillReturn.Add("5");
WillReturn.Add("1 3 4 2 5");
//8.986111111
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] XArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();
int UB = XArr.Max();
char[] BanArr = new char[UB + 1];
for (int I = 0; I <= UB; I++) {
BanArr[I] = '1';
}
foreach (int EachInt in XArr) {
BanArr[EachInt] = '0';
}
string BanStr = new string(BanArr);
double Answer = dfs(BanStr);
Console.WriteLine(Answer);
}
// 再帰
static double dfs(string pBan)
{
int UB = pBan.Length - 1;
// 1番左の0を求める
int Target = pBan.IndexOf('0');
if (Target == -1) return 0D;
// 1つ右がUB以下なら、ここに投げる
if (Target + 1 <= UB) {
Target++;
}
List<int> ZeroIndList = DeriveZeroIndList(pBan, Target);
var KouhoList = new List<double>();
char[] BanArr = pBan.ToCharArray();
// 1の場合は、コンプガチャ問題の期待値
if (ZeroIndList.Count == 1) {
return 3 + dfs(UpdateOne(pBan, ZeroIndList[0]));
}
else if (ZeroIndList.Count == 2) {
// 自己ループ以外になる確率
double NonLoopProb = 2D / 3D;
double NewEx = 1D / NonLoopProb; // 自己ループ以外になる確率の逆数
KouhoList.Add(1D / 2D * dfs(UpdateOne(pBan, ZeroIndList[0])));
KouhoList.Add(1D / 2D * dfs(UpdateOne(pBan, ZeroIndList[1])));
// 自己ループ以外の条件付確率 * 期待値を集計
NewEx += KouhoList.Sum();
return NewEx;
}
KouhoList.Add(1D / 3D * dfs(UpdateOne(pBan, ZeroIndList[0])));
KouhoList.Add(1D / 3D * dfs(UpdateOne(pBan, ZeroIndList[1])));
KouhoList.Add(1D / 3D * dfs(UpdateOne(pBan, ZeroIndList[2])));
return 1 + KouhoList.Sum();
}
// 盤面と指定座標を引数として、左右も含めた0の座標のListを返す
static List<int> DeriveZeroIndList(string pBan, int pBaseInd)
{
int UB = pBan.Length - 1;
var WillReturn = new List<int>();
if (pBaseInd - 1 >= 0) {
if (pBan[pBaseInd - 1] == '0') {
WillReturn.Add(pBaseInd - 1);
}
}
if (pBan[pBaseInd] == '0') {
WillReturn.Add(pBaseInd);
}
if (pBaseInd + 1 <= UB) {
if (pBan[pBaseInd + 1] == '0') {
WillReturn.Add(pBaseInd + 1);
}
}
return WillReturn;
}
// string型の引数のIndを1にUpdateする
static string UpdateOne(string pStr, int pInd)
{
char[] CharArr = pStr.ToCharArray();
CharArr[pInd] = '1';
return new string(CharArr);
}
}