有一个n*n的仅有数字组成的矩阵,每一个元素都是0~9的数字。
比如
123
456
789
每一行,可以获得字符串
每一列,可以获得一个字符串
列出这些字符串的所有子串
把这些子串当成一个整数,然后全部加起来。
求计算结果。
例如第一行,可以获得1、2、3、12、23、123
第一列可以获得1、4、7、14、47、147
多组测试数据
每组测试数据的第一行是一个n (1<=n<=1000)
接下来n行是矩阵。
输出结果模1,000,000,007(1e9+7)。
3 123 456 789
2784
分析:
根据取模运算具有如下性质
(a*b)%c = ((a%c)*(b%c))%c
(a+b)%c = ((a%c)+(b%c))%c
我们可以把这些字符串组成的数拆开来看。。
比如样例中第一行1、2、3、12、23、123,拆出1,10,100,2,2,20,20,3,3,3,这样的话,
第一位1,因为要作为组成数的个位,十位和百位,所以是1*(111)
第二位2,要作为数的个位和十位,而前面有一个数,所以是2*2*11;
第三位3,作为个位,前面有两个数,所以是3*1
这样我们就可以得到每个数对于整体的贡献,计算每个数的贡献取模求和,即为最后的结果。
代码如下:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const LL MOD=1e9+7; LL sum[1100]; char map1[1100][1100]; void init() { sum[1]=1; for(int i=2;i<=1005;i++) { sum[i]=(sum[i-1]*10%MOD+1)%MOD; } } int main() { ios::sync_with_stdio(false); init(); LL n; LL ans=0; while(cin>>n) { ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>map1[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { ans=(ans+sum[n-j+1]*(map1[i][j]-‘0‘)%MOD*j%MOD)%MOD; ans=(ans+sum[n-i+1]*(map1[i][j]-‘0‘)%MOD*i%MOD)%MOD; } cout<<ans<<endl; } return 0; }