4259. 【NOIP2015模拟10.22】矩形 (Standard IO)

Description

给定一个由数字(0-9)构成的字符串s。我们可以由此定义出size(s) * size(s) 大
小的矩阵b,其中b[i][j] = s[i] * s[j];请问在这个矩阵b中,有多少子矩形满足其中的b[i][j]的和为另一个给定的数字a。

Input

第一行一个整数a。
第二行字符串s。

Output

一个整数表示满足条件的子矩形数。

Sample Input

10
12345

Sample Output

6
【样例解释】
b 矩阵为:
01 02 03 04 05
02 04 06 08 10
03 06 09 12 15
04 08 12 16 20
05 10 15 20 25
和为 10 的子矩形有:
一、01 02 03 04
二、
01
02
03
04
三、04 06
四、
04
06
五、10
六、10
以上共六个。

Data Constraint

对 10%的输入数据:size(s)≤10
对30%的输入数据:size(s)≤100
对100%的输入数据:0 ≤a≤1000000000,size(s)≤4000

分析:

我们不难发现一个子矩形(x1,y1,x2,y2){左上角坐标和右下角坐标}内的和其实是
sum[x1..x2]*sum[y1..y2](sum即Σ,求和)

列如:s=325
9 6 15
6 4 10
15 10 25 (没错,因为第i,j个位就是s[i]*s[j],1,1就是s[1]*s[1]=3*3=9)
我们要求(1,1,2,1)这个矩阵即9 6
6 4就是(3+2)*(3+2)注意乘的是s里面的数。
所以下面所有矩阵的和都是第一行子矩阵的和的倍数。
即要枚举出符合题意的矩阵,应先找第一行的数,然后用找符合a/sum[x1…x2](指第一行从x1到x2的和)=sum[y1…y2](指第一列从y1到y2的和)的子矩阵的值分别有多少个。
我们可以开一个p数组来储存这些因数。
答案就是加上这些因数,因为我们已经找到这个因数(标位因数1)的另一个因数与因数1相乘等于a。
f [ i ] [ j ] = k = 1 i l = 1 j f [ k ] [ l ]
但若a=0时,就不符合上述定律,但我们仍可得出一些结论。
当找到因数1不为0时,则ans+=p[0],因为这个因数与0相加即得0;
当因数1等于0时,则ans+=lens(s的长度)*(lens+1)/2;
因为因数1下面的数都为0(与0相乘都是0)

120
240
000 

我们可以发现当以一个0为一个矩阵时(第三列,就是竖的第三个),有三个,当以2个0为一个矩阵时,则有两个,当以三个0为一个矩阵时,就有一个。可得结论lens+lens-1+lens-2….1
由等差数列可得 ( l e n s + 1 l e n s / 2

而且还要注意,看a的规模,s最大就是4000个9相加,也就是36000。所以我们需要判断得到的a/因数1=因数2不能大于36000,因为会数组越界,干扰了内存基本基本就WA\TLE\MLE,所以需要特判断。

猜你喜欢

转载自blog.csdn.net/ssl_trx/article/details/81006944
今日推荐