Problem:
Problem A : ID

A大学ではIDの入力ミスが多発していた。

そこで、A大学は入力ミス防止のため新しいIDを発行することにした。

新しいIDには入力ミス防止のためにIDが正しいかどうかチェックする方法がある。

・全ての桁の数字の総和を求める。

・ただし、右端の桁を１番目として、偶数番目の桁の数字を２倍にする。

・２倍することによって数字が１０以上になった時、１の位の数字と１０の位の数字を加算した数字をその桁の数字とする。

・総和が１０で割り切れれば正しいID、そうでなければ間違いとする。

例として、53579というIDをチェックする。

全ての桁の数字の総和を求めるので、

5 + 3 + 5 + 7 + 9

ただし、偶数番目の桁の数字を２倍にするので、

5 + 6 + 5 + 14 + 9

２倍することによって数字が１０以上になった時、１の位の数字と１０の位の数字を加算した数字をその桁の数字とするので、

5 + 6 + 5 + (1 + 4) + 9

以上より、総和は30となる。30は10で割り切れるので、53579は正しいIDである。

B君はA大学の大学生であり、新しいIDを発行してもらったが、IDの一部の桁を忘れてしまった。

しかし、忘れてしまった部分にどんな数字が入るか、いくつか候補を絞ることに成功した。

あなたの仕事は、B君のIDの正しい組み合わせが何通りあるかを求めることである。

Input

入力は以下のフォーマットで与えられる。

n
ID
m
a0 a1 ... am-1

nはIDの桁の数である。

IDの各桁には0~9の数字または忘れた桁であるということを示す'*'という文字が入る。

mは'*'に入る数字の候補の数である。

aiは'*'に入る数字の候補である。

入力は以下の制約を満たす

1 ≤ n ≤ 100,000

1 ≤ m ≤ 10

0 ≤ ai ≤ 9

1 ≤ '*'の数 ≤ 7

Output

答えの値を１行に出力せよ

Sample Input 1

5
5*57*
2
3 9

Sample Output 1

1

Sample Input 2

15
2***9*2*6*1199*
9
0 1 2 3 4 6 7 8 9

Sample Output 2

478297

Solution in C# (judge verdict: Accepted)

using System;

public class Hello
{
    public static void Main()
    {
        var n = int.Parse(Console.ReadLine().Trim());
        var s = Console.ReadLine().Trim();
        Console.ReadLine();
        string[] line = Console.ReadLine().Trim().Split(' ');
        var a = Array.ConvertAll(line, int.Parse);
        var s2 = s.ToCharArray();
        Array.Reverse(s2);
        var plus = 0; var pos = "";
        for (int i = 0; i < n; i++)
            if (i % 2 == 0 && s2[i] == '*') pos += "1";
            else if (i % 2 == 0 && s2[i] != '*') plus += int.Parse(s2[i].ToString());
            else if (i % 2 == 1 && s2[i] == '*') pos += "2";
            else plus += getDouble(int.Parse(s2[i].ToString()));
        plus %= 10;
        var res = 10 - plus;
        if (res == 10) res = 0;
        var dp = new int[pos.Length, 10];
        goDP(dp, pos, a);
        Console.WriteLine(dp[pos.Length-1,res]);
    }
    public static void goDP (int[,]dp,string pos, int[] a)
    {
        foreach (var x in a)
            if (pos[0] == '1') dp[0, x] = 1;
            else dp[0, getDouble(x)] = 1;
        for (int i = 1; i < pos.Length; i++)
            for (int j = 0; j < 10; j++)
            {
                foreach (var x in a)
                    if (pos[i] == '1') dp[i, (j + x) % 10] += dp[i - 1, j];
                    else dp[i, (j + getDouble(x)) % 10] += dp[i - 1, j];
            }
    }
    public static int getDouble(int a)
    {
        return a >= 5 ? 2 * a - 9 : 2 * a;
    }
}