acdream(16) J-Sum

题目链接:点击打开链接


对于a[i][j] (从a[1][1]开始),对于所在行 ,在包含它的所有数中 ,从k=0至i-1,做为a[i][j]*(10的k次幂)各i次。如123中的1 ,做100,10,1各1次,2做2,20各两次。

列同理。

因此预处理打一个1,11,111.。。。。。的表,此表用ni[]存储, 对于a[i][j],在整体计算中的和为a[i][j]*i*ni[i]。


代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#define ll long long
ll mi[1010];
ll ni[1010];
using namespace std;
const ll mod = 1e9+7;
int N;
char c[1005];
int a[1005][1005];

ll cal(int x,int m,int n){
    ll res=0;
    res+=(m+1)*x*ni[N-m-1]%mod;

    res+=(n+1)*x*ni[N-n-1]%mod;

    res%=mod;
    return res;
}

int main()
{
    mi[0]=1;
    ni[0]=1;
    for(int i=1;i<=1005;i++){
            mi[i]=mi[i-1]*10%mod;
            ni[i]=ni[i-1]+mi[i];
            ni[i]%=mod;

    }

    while(~scanf("%d",&N)){
            ll res=0;
            for(int i=0;i<N;i++){
                    scanf("%s",c);
                    for(int j=0;j<N;j++){
                            a[i][j]=(int)(c[j]-'0');
                    }
            }
            for(int i=0;i<N;i++){
                    for(int j=0;j<N;j++){
                            ll t=cal(a[i][j],i,j)%mod;
                            res+=t;
                            res%= mod;
                    }
            }
            printf("%lld\n",res);
    }
    return 0;
}



你可能感兴趣的:(acdream(16) J-Sum)