Problem:
Problem C:
Minimal Backgammon
Here is a very simple variation of the game backgammon, named “Minimal Backgammon”. The game is played by only one player, using only one of the dice and only one checker (the token used by the player).
The game board is a line of (
N
+ 1) squares labeled as 0 (the start) to
N
(the goal). At the beginning, the checker is placed on the start (square 0). The aim of the game is to bring the checker to the goal (square
N
). The checker proceeds as many squares as the roll of the dice. The dice generates six integers from 1 to 6 with equal probability.
The checker should not go beyond the goal. If the roll of the dice would bring the checker beyond the goal, the checker retreats from the goal as many squares as the excess. For example, if the checker is placed at the square (
N
- 3), the roll "5" brings the checker to the square (
N
- 2), because the excess beyond the goal is 2. At the next turn, the checker proceeds toward the goal
as usual.
Each square, except the start and the goal, may be given one of the following two special instructions.
Lose one turn (labeled "
L
" in Figure 2) If the checker stops here, you cannot move the checker in the next turn.
Go back to the start (labeled "
B
" in Figure 2)
If the checker stops here, the checker is brought back to the start.
Figure 2: An example game
Given a game board configuration (the size
N
, and the placement of the special instructions), you are requested to compute the probability with which the game succeeds within a given number of turns.
Input
The input consists of multiple datasets, each containing integers in the following format.
N T L B
Lose
1
...
Lose
L
Back
1
...
Back
B
N
is the index of the goal, which satisfies 5 ≤
N
≤ 100.
T
is the number of turns. You are requested to compute the probability of success within
T
turns.
T
satisfies 1 ≤
T
≤ 100.
L
is the number of squares marked “Lose one turn”, which satisfies 0 ≤
L
≤
N
- 1.
B
is the number of squares marked “Go back to the start”, which satisfies 0 ≤
B
≤
N
- 1. They are separated by a space.
Lose
i
's are the indexes of the squares marked “Lose one turn”, which satisfy 1 ≤
Lose
i
≤
N
- 1. All
Lose
i
's are distinct, and sorted in ascending order.
Back
i
's are the indexes of the squares marked “Go back to the start”, which satisfy 1 ≤
Back
i
≤
N
- 1. All
Back
i
's are distinct, and sorted in ascending order. No numbers occur both in
Lose
i
's and
Back
i
's.
The end of the input is indicated by a line containing four zeros separated by a space.
Output
For each dataset, you should answer the probability with which the game succeeds within the
given number of turns. The output should not contain an error greater than 0.00001.
Sample Input
6 1 0 0
7 1 0 0
7 2 0 0
6 6 1 1
2
5
7 10 0 6
1
2
3
4
5
6
0 0 0 0
Output for the Sample Input
0.166667
0.000000
0.166667
0.619642
0.000000

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
  int N, T, L, B;
  cout << fixed << setprecision(6);
  while (cin >> N >> T >> L >> B, N) {
    map<int, bool> Lose;
    for (int i = 0; i < L; i++) {
      int l;
      cin >> l;
      Lose[l] = true;
    }
    map<int, bool> Back;
    for (int i = 0; i < B; i++) {
      int b;
      cin >> b;
      Back[b] = true;
    }

    vector<vector<double>> dp(T + 2, vector<double>(N + 1, 0.0));
    dp[0][0] = 1.0;
    auto f = [&](int n, int p) {
      return (Lose[p]) ? n + 1 : n;
    };
    auto g = [&](int p) {
      int q = min(N, p) - max(0, p - N);
      return (Back[q]) ? 0 : q;
    };
    for (int i = 0; i < T; i++) {
      for (int j = 0; j < N; j++) {
        for (int k = 0; k < 6; k++) {
          dp[f(i + 1, j)][g(j + k + 1)] += 1.0 / 6.0 * dp[i][j];
        }
      }
    }

    double ans = 0;
    for (int i = 0; i < T + 1; i++) {
      ans += dp[i][N];
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3332
final_rank: 9

code_snippet: //#include "bits/stdc++.h"

#include <iostream>
#include <vector>
#include <iomanip>
// #include <map>
// #include <string>
// #include <algorithm>
// #include <numeric>
// #include <limits>

using namespace std;

size_t n;
size_t t;
size_t l;
size_t b;
size_t s;
double matrix[200][200]; // [from][to]
double ans[200];

void printAns() {
	for (size_t i = 0; i < s; i++) {
		cout << fixed << setprecision(6) << ans[i] << ' ';
	}
	cout << endl;
}

void print() {
	for (size_t i = 0; i < s; i++) {
		for (size_t j = 0; j < s; j++) {
			cout << fixed << setprecision(6) << matrix[i][j] <<  ' ';
		}
		cout << endl;
	}
	cout << endl;
}

void prod() {
	double bef[200];
	for (size_t i = 0; i < s; i++) {
		bef[i] = ans[i];
	}
	for (size_t to = 0; to < s; to++) {
		double sum = 0;
		for (size_t from = 0; from < s; from++) {
			sum += bef[from] * matrix[from][to];
		}
		ans[to] = sum;
	}
}

void makeMatrix() {
	for (size_t i = 0; i < s; i++) {
		for (size_t j = 0; j < s; j++) {
			matrix[i][j] = 0;
		}
		ans[i] = 0;
	}
	ans[0] = 1;
	for (size_t i = 0; i < n - 1; i++) {
		for (size_t j = i + 1; j <= i + 6; j++) {
			if (j >= n) {
				auto key = (n - 1) - (j - (n - 1));
				matrix[i][key] += 1 / (double) 6;
				continue;
			}
			matrix[i][j] += 1 / (double) 6;
		}
	}
}

void solve() {
	n = n + 1;
	s = n + l;
	makeMatrix();
	// for l
	for (size_t i = 0; i < l; i++) {
		size_t target;
		cin >> target;
		//std::cout << "debug " << n + i << std::endl; // debug
		matrix[n + i][target] = 1;
		for (size_t from = 0; from < n; from++) {
			matrix[from][n + i] = matrix[from][target];
			matrix[from][target] = 0;
		}
	}
	// for b
	for (size_t i = 1; i <= b; i++) {
		size_t target;
		cin >> target;
		for (size_t from = 0; from < n; from++) {
			matrix[from][0] += matrix[from][target];
			matrix[from][target] = 0;
		}
	}
	// for goal
	matrix[n - 1][n - 1] = 1;
	// print();
	// cout << endl;
	for (size_t i = 0; i < t; i++) {
		// printAns();
		// cout << endl;
		prod();
	}
	// printAns();
	// cout << endl;
	cout << fixed << setprecision(6) << ans[n - 1] << endl;
}

int main() {

	while (true) {
		cin >> n >> t >> l >> b;
		if (n == 0) {
			break;
		}
		solve();
	}

	//std::cout << "\e[38;5;0m\e[48;5;40m --- end ---  \e[m" << std::endl; // debug
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3480
final_rank: 10

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <map>

using namespace std;
#define DEBUG(X) cerr<<__LINE__<<" "<<#X<<": "<<X<<endl;
#define sci(x) int x;scanf("%d",&x);
#define scii(x, y) int x,y;scanf("%d%d",&x,&y);
#define REP(i, y) for(int i=0;i<y;i++)
#define FOR(i,x,y) for(int i=x;i<y;i++)
#define DUMPP(A, n, m) for (auto x=begin(A); x != begin(A)+n;x++) {for (auto y=begin(*x); y != begin(*x)+m;)cerr <<*y++<< ' '; cerr<<endl;};

const int L_FLAG = 1;
const int B_FLAG = 2;

const int MAX_N = 110;
const int MAX_T = 110;
double dp[MAX_N][MAX_T];


int floor(int i, int N) {
  return i>N?N-(i-N):i;
}

int main() {
  // N: ??¢?????°
  // T: ?????°
  // L: 1???????????????????????¢?????°
  // B: ?????????????????????????????¢?????°
  int N,T,L,B;
  while(scanf("%d%d%d%d", &N, &T, &L, &B), N) {
    memset(&dp, 0, sizeof(dp));
    map<int, int> mp;
    REP(i, L) {
      sci(L_i)
      mp[L_i] = L_FLAG;
    }
    REP(i, B) {
      sci(B_i)
      mp[B_i] = B_FLAG;
    }

    // main loop
    REP(t, T) {
      REP(i, N) {  // N+1?????????????????????N???????§???????????????¨????????????
        if (i==0&&t==0) dp[i][t]=1.0;

        FOR(j, 1, 7) {
          int npos = floor(i+j, N);
          int nturn = t + 1;
          if (mp[npos] == L_FLAG) nturn += 1;
          if (mp[npos] == B_FLAG) npos = 0;
          dp[npos][nturn] += dp[i][t] / 6.;
        }
      }
    }
    //DUMPP(dp, N+1, T+1);
    double ans=0.;
    REP(i,T+1) ans+=dp[N][i];
    printf("%f\n", ans);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3220
final_rank: 7

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<iomanip>
using namespace std;
main()
{
	int n,m,l,b;
	while(cin>>n>>m>>l>>b,n)
	{
		vector<int> back,lose;
		for(int i=0;i<l;i++)
		{
			int u;cin>>u;
			lose.push_back(u);
		}
		for(int i=0;i<b;i++)
		{
			int u;cin>>u;
			back.push_back(u);
		}
		double dp[102][101]={};//tarn,place
		dp[0][0]=1.0;
		for(int i=0;i<m;i++)
		{
			for(int p=0;p<n;p++)
			{
				for(int j=1;j<=6;j++)
				{
					int u=p+j;
					int t=1;
					if(u>n)u=n-(u-n);
					bool flag=false;
					for(int k=0;k<l;k++)if(u==lose[k])flag=true;
					if(flag)t++;
					flag=false;
					for(int k=0;k<b;k++)if(u==back[k])flag=true;
					if(flag)u=0;
					dp[i+t][u]+=dp[i][p]/6.0;
				}
			}
			dp[i+1][n]+=dp[i][n];
		}
		cout<<fixed<<setprecision(9)<<dp[m][n]+dp[m+1][n]<<endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3268
final_rank: 8

code_snippet: #include <iostream>
#include <stdio.h>
#define MAX_N 100
#define MAX_T 100
using namespace std;

double mbg(int N, int T, int L, int B, int Lose[], int Back[]) {
	int t;
	double p_goal = 0;
	double ways[MAX_T + 2][MAX_N + 1] = { { 0 } };

	t = 0;
	ways[0][0] = 1.0;
	while (t < T) {
		for (int i = 0; i < N; ++i) {
			for (int j = 1; j <= 6; ++j) {
				if ((i + j) <= N) {
					for (int k = 0; k < L; ++k) {
						if ((i + j) == Lose[k]) {
							ways[t + 2][i + j] += ways[t][i] / 6;
							goto escape1;
						}
					}
					for (int k = 0; k < B; ++k) {
						if ((i + j) == Back[k]) {
							ways[t + 1][0] += ways[t][i] / 6;
							goto escape1;
						}
					}
					ways[t + 1][i + j] += ways[t][i] / 6;
				escape1:;
				}
				else{
					for (int k = 0; k < L; ++k) {
						if ((2 * N - (i + j)) == Lose[k]) {
							ways[t + 2][2 * N - (i + j)] += ways[t][i] / 6;
							goto escape2;
						}
					}
					for (int k = 0; k < B; ++k) {
						if ((2 * N - (i + j)) == Back[k]) {
							ways[t + 1][0] += ways[t][i] / 6;
							goto escape2;
						}
					}
					ways[t + 1][2 * N - (i + j)] += ways[t][i] / 6;
				escape2:;
				}
			}
		}
		t++;
	}

	for (int i = 1; i <= T; ++i) {
		p_goal += ways[i][N];
	}
	return p_goal;
}

int main() {
	int N, T, L, B;
	while (1) {
		int *Lose, *Back;
		Lose = new int[MAX_N]; Back = new int[MAX_N];
		cin >> N >> T >> L >> B;
		if (N == 0 && T == 0 && L == 0 && B == 0) break;
		for (int i = 0; i < L; ++i) cin >> Lose[i];
		for (int i = 0; i < B; ++i) cin >> Back[i];
		printf("%.6f\n", mbg(N, T, L, B, Lose, Back));
		delete[] Lose; delete[] Back;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1304
final_rank: 1

code_snippet: #include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;


int main(){
  while (1){
    int N,T,L,B;
    cin >>N >>T >>L >>B;
    if(N==0) break;

    vector<bool> lose(N+1);
    vector<bool> back(N+1);
    //?????????
    fill(lose.begin(), lose.end(), false);
    fill(back.begin(), back.end(), false);

    for(int i=0; i<L; ++i){
      int t; cin>>t;
      lose[t]=true;
      if(t>=N-5) lose[2*N-t]=true;
    }
    for(int i=0; i<B; ++i){
      int t; cin>>t;
      back[t]=true;
      if(t>=N-5) back[2*N-t]=true;
    }

    //p[t][n]:t?????????????????????n??????????¢????
    double p[101][106];

    //????????¶???
    p[0][0]=1.0;
    for(int i=1; i<=105; ++i) p[0][i]=0.0;

    for(int t=1; t<=T; ++t){
      //printf("go %d turn\n", t);

      double suuuu=0.0;

      for(int n=0; n<=N+5; ++n){
        p[t][n]=0.0;

        if(n==N) p[t][n]+=p[t-1][n];

        if(lose[n]){
          int pp=1;
          double tmp=0.0;
          for(int i=t-1; i>=0; --i){
            tmp+=p[i][n]*pp;
            pp*=-1;
          }
          p[t][n] += tmp;
          //printf("%d, %d: tmp=%lf\n ",t, n, tmp);
        }

        for(int k=1; k<=6; ++k){
          if(n-k<0) break;
          if(n-k==N) continue;
          //printf("n: %d, k: %d\n", n,k);

          if(lose[n-k]){
            //printf("  go go n: %d, k: %d   ", n,k);

            int pp=1;
            double tmp2=0.0;
            for(int i=t-2; i>=0; --i){
              tmp2+=p[i][n-k]*pp;
              pp*=-1;
            }
            //printf(" tmp2=%lf\n", tmp2);

            p[t][n] +=tmp2/6.0;
          }
          else p[t][n] += p[t-1][n-k]/6.0;

        }

        //printf("p[%d][%d] = %lf\n",t, n, p[t][n]);
        suuuu += p[t][n];

        if(n>N){
          p[t][N-(n%N)] += p[t][n];
          p[t][n]=0.0;
        }
      }

      //printf("suuuu = %lf\n", suuuu);

      for(int n=1; n<N; ++n){
        if(back[n]){
          //printf("back %d\n", n);
          p[t][0]+=p[t][n];
          p[t][n]=0.0;
        }
      }

      /*
      double checksum=0.0;
      for(int n=0; n<=N; ++n){
        checksum+=p[t][n];
        printf("p[%d][%d] = %.10lf\n", t, n, p[t][n]);
      }
      printf(" ch=%.10lf\n", checksum);
      */
    }

    printf("%.10lf\n", p[T][N]);
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1304
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
typedef vector<long double> V;
 
int main () {
    int N, T, L, B;
    while (cin >> N >> T >> L >> B, N || T || L || B) {
        V lose(L,0), back(B,0);
 
        for (int i = 0; i < L; i++) cin >> lose[i];
        for (int i = 0; i < B; i++) cin >> back[i];
 
        vector<V> dp(T+3, V(N+1));
        dp[0][0] = 1;
 
        for (int i = 0; i < T; i++) {
            dp[i+1][N] += dp[i][N];
            for (int j = 0; j < N; j++) {
                if (dp[i][j] > 0) {
                    for (int k = 1; k < 7; k++) {
                        int next = j + k <= N ? j + k : N * 2 - (j + k);
                        if (find(lose.begin(), lose.end(), next) != lose.end()) {
                            dp[i+2][next] += dp[i][j] / 6;
                        } else if (find(back.begin(), back.end(), next) != back.end()) {
                            dp[i+1][0] += dp[i][j] / 6;
                        } else {
                            dp[i+1][next] += dp[i][j] / 6;
                        }
                    }
                }
            }
        }
 
        printf("%.6Lf\n", dp[T][N]);
    }
 
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1384
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef vector<double> V;

int main () {
    int N, T, L, B;
    while (cin >> N >> T >> L >> B, N || T || L || B) {
        V lose(L,0), back(B,0);

        for (int i = 0; i < L; i++) cin >> lose[i];
        for (int i = 0; i < B; i++) cin >> back[i];

        vector<V> dp(T+3, V(N+1));
        dp[0][0] = 1;

        for (int i = 0; i < T; i++) {
            dp[i+1][N] += dp[i][N];
            for (int j = 0; j < N; j++) {
                if (dp[i][j] > 0) {
                    for (int k = 1; k < 7; k++) {
                        int next = j + k <= N ? j + k : N * 2 - (j + k);
                        if (find(lose.begin(), lose.end(), next) != lose.end()) {
                            dp[i+2][next] += dp[i][j] / 6;
                        } else if (find(back.begin(), back.end(), next) != back.end()) {
                            dp[i+1][0] += dp[i][j] / 6;
                        } else {
                            dp[i+1][next] += dp[i][j] / 6;
                        }
                    }
                }
            }
        }

        printf("%.6f\n", dp[T][N]);
    }

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1344
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef vector<double> V;

int main () {
    int N, T, L, B;
    while (cin >> N >> T >> L >> B, N || T || L || B) {
        V lose(L,0), back(B,0);

        for (int i = 0; i < L; i++) cin >> lose[i];
        for (int i = 0; i < B; i++) cin >> back[i];

        vector<V> dp(T+3, V(N+1));
        dp[0][0] = 1.L;

        for (int i = 0; i < T; i++) {
            dp[i+1][N] += dp[i][N];
            for (int j = 0; j < N; j++) {
                if (dp[i][j] > 0) {
                    for (int k = 1; k < 7; k++) {
                        int next = j + k <= N ? j + k : N * 2 - (j + k);
                        if (find(lose.begin(), lose.end(), next) != lose.end()) {
                            dp[i+2][next] += dp[i][j] / 6;
                        } else if (find(back.begin(), back.end(), next) != back.end()) {
                            dp[i+1][0] += dp[i][j] / 6;
                        } else {
                            dp[i+1][next] += dp[i][j] / 6;
                        }
                    }
                }
            }
        }

        printf("%.6f\n", dp[T][N]);
    }

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1344
final_rank: 2

code_snippet: // Header {{{
// includes {{{
#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <sys/time.h>
#include <unistd.h>
#include <vector>
// }}}
using namespace std;
// consts {{{
static const int INF = 1e9;
static const double PI = acos(-1.0);
static const double EPS = 1e-10;
// }}}
// typedefs {{{
typedef long long int LL;
typedef unsigned long long int ULL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef vector<ULL> VULL;
typedef vector<VULL> VVULL;
typedef vector<double> VD;
typedef vector<VD> VVD;
typedef vector<bool> VB;
typedef vector<VB> VVB;
typedef vector<char> VC;
typedef vector<VC> VVC;
typedef vector<string> VS;
typedef vector<VS> VVS;
typedef pair<int, int> PII;
typedef complex<int> P;
// }}}
// macros & inline functions {{{
// syntax sugars {{{
#define FOR(i, b, e) for (typeof(e) i = (b); i < (e); ++i)
#define FORI(i, b, e) for (typeof(e) i = (b); i <= (e); ++i)
#define REP(i, n) FOR(i, 0, n)
#define REPI(i, n) FORI(i, 0, n)
#define OPOVER(_op, _type) inline bool operator _op (const _type &t) const
// }}}
// conversion {{{
inline int toInt(string s) { int v; istringstream sin(s); sin>>v; return v; }
template<class T> inline string toString(T x) { ostringstream sout; sout<<x; return sout.str(); }
// }}}
// array and STL {{{
#define ARRSIZE(a) ( sizeof(a) / sizeof(a[0]) )
#define ZERO(a, v) ( assert(v == 0 || v == -1), memset(a, v, sizeof(a)) )
#define F first
#define S second
#define MP(a, b) make_pair(a, b)
#define SIZE(a) ((LL)a.size())
#define PB(e) push_back(e)
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EACH(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define REACH(c, it) for(typeof((c).rbegin()) it=(c).rbegin(); it!=(c).rend(); ++it)
#define EXIST(s, e) ((s).find(e) != (s).end())
// }}}
// bit manipulation {{{
// singed integers are not for bitwise operations, specifically arithmetic shifts ('>>', and maybe not good for '<<' too)
#define IS_UNSIGNED(n) (!numeric_limits<typeof(n)>::is_signed)
#define BIT(n) (assert(IS_UNSIGNED(n)), assert(n < 64), (1ULL << (n)))
#define BITOF(n, m) (assert(IS_UNSIGNED(n)), assert(m < 64), ((ULL)(n) >> (m) & 1))
inline int BITS_COUNT(ULL b) { int c = 0; while(b != 0) { c += (b & 1); b >>= 1; } return c; }
inline int MSB(ULL b) { int c = 0; while(b != 0) { ++c; b >>= 1; } return c-1; }
inline int MAKE_MASK(ULL upper, ULL lower) { assert(lower < 64 && upper < 64 && lower <= upper); return (BIT(upper) - 1) ^ (BIT(lower) - 1); }
// }}}
// for readable code {{{
#define EVEN(n) (n % 2 == 0)
#define ODD(n) (!EVEN(n))
// }}}
// debug {{{
#define arrsz(a) ( sizeof(a) / sizeof(a[0]) )
#define dprt(fmt, ...) if (opt_debug) { fprintf(stderr, fmt, ##__VA_ARGS__); }
#define darr(a) if (opt_debug) { copy( (a), (a) + arrsz(a), ostream_iterator<int>(cerr, " ") ); cerr << endl; }
#define darr_range(a, f, t) if (opt_debug) { copy( (a) + (f), (a) + (t), ostream_iterator<int>(cerr, " ") ); cerr << endl; }
#define dvec(v) if (opt_debug) { copy( ALL(v), ostream_iterator<int>(cerr, " ") ); cerr << endl; }
#define darr2(a) if (opt_debug) { FOR(__i, 0, (arrsz(a))){ darr( (a)[__i] ); } }
#define WAIT() if (opt_debug) { string _wait_; cerr << "(hit return to continue)" << endl; getline(cin, _wait_); }
#define dump(x) if (opt_debug) { cerr << " [L" << __LINE__ << "] " << #x << " = " << (x) << endl; }
#define dumpl(x) if (opt_debug) { cerr << " [L" << __LINE__ << "] " << #x << endl << (x) << endl; }
#define dumpf() if (opt_debug) { cerr << __PRETTY_FUNCTION__ << endl; }
#define where() if (opt_debug) { cerr << __FILE__ << ": " << __PRETTY_FUNCTION__ << " [L: " << __LINE__ << "]" << endl; }
#define show_bits(b, s) if(opt_debug) { REP(i, s) { cerr << BITOF(b, s-1-i); if(i%4 == 3) cerr << ' '; } cerr << endl; }

// ostreams {{{
// complex
template<typename T> ostream& operator<<(ostream& s, const complex<T>& d) {return s << "(" << d.real() << ", " << d.imag() << ")";}

// pair
template<typename T1, typename T2> ostream& operator<<(ostream& s, const pair<T1, T2>& d) {return s << "(" << d.first << ", " << d.second << ")";}

// vector
template<typename T> ostream& operator<<(ostream& s, const vector<T>& d) {
	int len = d.size();
	REP (i, len) {
		s << d[i]; if (i < len - 1) s << "\t";
	}
	return s;
}

// 2 dimentional vector
template<typename T> ostream& operator<<(ostream& s, const vector< vector<T> >& d) {
	int len = d.size();
	REP (i, len) {
		s << d[i] << endl;
	}
	return s;
}

// map
template<typename T1, typename T2> ostream& operator<<(ostream& s, const map<T1, T2>& m) {
	s << "{" << endl;
	for (typeof(m.begin()) itr = m.begin(); itr != m.end(); ++itr) {
		s << "\t" << (*itr).first << " : " << (*itr).second << endl;
	}
	s << "}" << endl;
	return s;
}
// }}}
// }}}
// }}}
// time {{{
inline double now(){ struct timeval tv; gettimeofday(&tv, NULL); return (static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_usec) * 1e-6); }
// }}}
// string manipulation {{{
inline VS split(string s, char delimiter) { VS v; string t; REP(i, s.length()) { if(s[i] == delimiter) v.PB(t), t = ""; else t += s[i]; } v.PB(t); return v; }
inline string join(VS s, string j) { string t; REP(i, s.size()) { t += s[i] + j; } return t; }
// }}}
// geometry {{{
#define Y real()
#define X imag()
// }}}
// 2 dimentional array {{{
P dydx4[4] = { P(-1, 0), P(0, 1), P(1, 0), P(0, -1) };
P dydx8[8] = { P(-1, 0), P(0, 1), P(1, 0), P(0, -1), P(-1, 1), P(1, 1), P(1, -1), P(-1, -1) };
int g_height, g_width;
bool in_field(P p) {
	return (0 <= p.Y && p.Y < g_height) && (0 <= p.X && p.X < g_width);
}
// }}}
// input and output {{{
inline void input(string filename) {
	freopen(filename.c_str(), "r", stdin);
}
inline void output(string filename) {
	freopen(filename.c_str(), "w", stdout);
}
// }}}
// }}}

// Header under development {{{

int LCM(int a, int b) {
	// FIXME
	return a * b;
}

// Fraction class {{{
// ref: http://martin-thoma.com/fractions-in-cpp/
class Fraction {
	public:
		ULL numerator;
		ULL denominator;
		Fraction(ULL _numerator, ULL _denominator) {
			assert(_denominator > 0);
			numerator = _numerator;
			denominator = _denominator;
		};

		Fraction operator*(const ULL rhs) {
			return Fraction(this->numerator * rhs, this->denominator);
		};

		Fraction operator*(const Fraction& rhs) {
			return Fraction(this->numerator * rhs.numerator, this->denominator * rhs.denominator);
		}

		Fraction operator+(const Fraction& rhs) {
			ULL lcm = LCM(this->denominator, rhs.denominator);
			ULL numer_lhs = this->numerator * (this->denominator / lcm);
			ULL numer_rhs = rhs.numerator * (rhs.numerator / lcm);
			return Fraction(numer_lhs + numer_rhs, lcm);
		}

		Fraction& operator+=(const Fraction& rhs) {
			Fraction result = (*this) + rhs;
			this->numerator = result.numerator;
			this->denominator = result.denominator;
			return *this;
		}
};

std::ostream& operator<<(std::ostream &s, const Fraction &a) {
	if (a.denominator == 1) {
		s << a.numerator;
	} else {
		s << a.numerator << "/" << a.denominator;
	}
	return s;
}

// }}}

// }}}

bool opt_debug = false;

int main(int argc, char** argv) {
	std::ios_base::sync_with_stdio(false);
	// set options {{{
	int __c;
	while ( (__c = getopt(argc, argv, "d")) != -1 ) {
		switch (__c) {
			case 'd':
				opt_debug = true;
				break;
			default:
				abort();
		}
	}
	// }}}

	// input("./inputs/0.txt");
	// output("./outputs/0.txt");

	enum _filed_type {
		NOTHING,
		LOSE,
		BACK
	};

	int N, T, L, B;
	while (cin >> N >> T >> L >> B, N | T | L | B) {
		VI field(N+1, NOTHING);
		REP (i, L) {
			int l; cin >> l;
			field[l] = LOSE;
		}
		REP (i, B) {
			int b; cin >> b;
			field[b] = BACK;
		}

		VVD dp(T+1, VD(N+1, 0));
		dp[0][0] = 1;
		FOR (t, 1, T + 1) {
			REP (n, N + 1) {
				FOR (d, 1, 7) { // dice
					VI prevs;
					int p1 = n - d;
					int p2 = N - (d - (N - n));
					prevs.PB(n - d);
					if (p2 != p1) {
						prevs.PB(N - (d - (N - n)));
					}

					REP (i, prevs.size()) {
						int prev = prevs[i];
						if (0 <= prev && prev < N) {
							if (field[n] == LOSE) {
								if (t-2 >= 0) {
									dp[t][n] += dp[t-2][prev] * (1 / 6.0);
								}
							} else if (field[n] == BACK) {
								dp[t][0] += dp[t-1][prev] * (1 / 6.0);
							} else {
								dp[t][n] += dp[t-1][prev] * (1 / 6.0);
							}
						}
					}
				}
			}
		}

		double ans = 0;
		FOR (t, 1, T+1) {
			ans += dp[t][N];
		}
		printf("%.10lf\n", ans);
	}

	return 0;
}

// vim: foldmethod=marker
accuracy: 1
time_ms: 30
memory_kb: 1364
final_rank: 11

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <cmath>
#include <string>
#include <sstream>
#include <iomanip>
#include <complex>
using namespace std;

#define ll long long
#define vvi vector< vector<int> >
#define vi vector<int>
#define All(X) X.begin(),X.end()
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define pi 3.14159265359
#define shosu(X) fixed << setprecision(X)
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

vi B,L;
int n,t,l,b;
long double dp[103][103];//dp[i][j]:= i?????????????????????j?????????
int main(){
	while(1){
		cin >> n >> t >> l >> b;
		REP(i,101) REP(j,101) dp[i][j] = 0;
		B.clear(); L.clear();
		if(n==0&&t==0&&l==0&&b==0) break;
		int tmp;
		REP(i,l){
			cin >> tmp;
			L.pb(tmp);
		}
		REP(i,b){
			cin >> tmp;
			B.pb(tmp);
		}
		dp[0][0] = 1.0;
		REP(i,t){
			REP(j,n){
				FOR(k,1,7){
					int pos = j + k;
					if(pos > n) pos = n - (k - (n - j));
					REP(w,B.size()){
						if(pos == B[w]) pos = 0;
					}
					bool Skipflag = false;
					REP(w,L.size()){
						if(pos == L[w]) Skipflag = true;
					}

					if(!Skipflag) dp[i+1][pos] += dp[i][j]*(1.0/6.0);
					else dp[i+2][pos] += dp[i][j]*(1.0/6.0);
				}
			}
		}
		long double ans = 0;
		FOR(i,1,t+1) ans += dp[i][n];
		cout << shosu(10) << ans << endl;

	}
}
accuracy: 1
time_ms: 20
memory_kb: 1456
final_rank: 6