Expection of String HDU - 5576

Frog has just learned how to multiply two numbers. Now he wants to do some exercise.

He wrote a string on the paper, which only contains digits and a single × as the operator. If the × appears at the front or the end of the string, he regards the result as zero, otherwise he does the calculation as a normal multiplication.

After some play, he wonders a new problem: for a initial string, each time he randomly choose two characters and swap their positions. He will do this again and again, say for K times, he wants to know the expected calculation result for the newest string that he gets.

It can be shown that their can be (n2)K ways(Same as (C2n)K) for the whole swap operations, so if the expected result is x, you need to output x×(n2)K
as an integer.
Input
First line contains an integer T, which indicates the number of test cases.

Every test case begins with an integers K, which is the numbers of times the Frog can swap characters.

The second line of each test case contains the string Frog plays with, which only contains digits and exactly one multiplication operator, written as ‘∗’.

⋅ 1≤T≤100.

⋅ the string’s length is L.

⋅ for 70% data, 1≤L≤10 and 0≤K≤5.

⋅ for 95% data, 1≤L≤20 and 0≤K≤20.

⋅ for 100% data, 1≤L≤50 and 0≤K≤50
.
Output
For every test case, you should output ” Case #x: y”, where x indicates the case number and counts from 1 and y is the result.

Because y could be very large, just mod it with 109+7
.
Sample Input

2
1
1*2
2
1*2

Sample Output

Case #1: 2
Case #2: 6

题意:给出一个长度为55的字符串,由数字和字母×组成,每次可以选择任意两个字符交换位置,如果×在两旁则贡献为0,否则贡献就是左边的数加上右边的数,问所有情况的贡献和;
做法:对于两个位置a,b,任意的交换他们里面的数,对于所有的情况,如果×在a,b之间,位置为x,那么贡献就是a*b*pow(10,x-a-1)*pow(10,n-b-1),那么枚举3个位置a,b,c(a < b < c),所有结果中如果b上为×,那么对答案的贡献为a*b*pow(10,x-a-1)*pow(10,n-b-1),枚举3个位置,dfs(x,y,z,d) 代表在进行了d次操作后,a上为x,b上为y,c上为z的情况下的贡献,记忆话搜索就可以了,
ps:有一个地方我调试了很久,就是在递归的过程中我用全局变量保存了一个值,这个值会在递归的过程中发生变化,因此答案是莫名奇妙的,总结就是以后在递归的过程中在不是确切需要的情况下尽量不要使用全局变量,

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

int dp[15][15][15][55];
char st[55];
int x[55],cnt[15];
int n,k;
int qp[55];
const int mod = 1e9+7;
void add(int &x,int y){
    x += y;
    if(x >= mod) x -= mod;
}
int dfs(int a,int b,int c,int d){
    if(d == k){
        return b == 10 ? a*c : 0;
    }
    if(dp[a][b][c][d] != -1) return dp[a][b][c][d];
    int ret = 0;
    add(ret,dfs(a,c,b,d+1));
    add(ret,dfs(b,a,c,d+1));
    add(ret,dfs(c,b,a,d+1));
    if(n > 4) add(ret,1LL*(n-3)*(n-4)/2*dfs(a,b,c,d+1)%mod);
    int cns[11];

    if(d == k-1){

    }

    for(int i = 0;i <= 10;i ++) cns[i] = cnt[i];
    cns[a]--,cns[b]--,cns[c]--;
    for(int i = 0;i <= 10;i ++){
        int now = cns[i];
        if(now == 0) continue;
        add(ret,1LL*now*dfs(i,b,c,d+1)%mod);
        add(ret,1LL*now*dfs(a,i,c,d+1)%mod);
        add(ret,1LL*now*dfs(a,b,i,d+1)%mod);
   }
    //cout << a << ' '<< b<<' '<< c << ' '<< d<< ' '<< ret <<endl;
    return dp[a][b][c][d] = ret;
}


int main(){
    int T;
    long long tmp = 1;
    for(int i = 0;i < 55;i ++){
        qp[i] = tmp ;
        tmp = tmp*10%mod;
    }
    cin >> T;
    for(int kase = 1;kase <= T;kase ++){
        memset(dp,-1,sizeof(dp));
        scanf("%d",&k);
        scanf("%s",st);
        n =strlen(st);
        memset(cnt,0,sizeof(cnt));
        for(int i = 0;i < n;i ++){
            x[i] = st[i]=='*'?10:st[i]-'0';
            cnt[x[i]]++;
        }
        int ans = 0;
        for(int i = 0;i < n;i ++){
            for(int j = i+1;j < n;j ++){
                for(int k = j+1;k < n;k ++){
                    add(ans,1LL*qp[j-i-1]*qp[n-k-1]%mod*dfs(x[i],x[j],x[k],0)%mod);
                }
            }
        }
        printf("Case #%d: ",kase);
        cout << ans << endl;
    }




    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/81111805