Matrix

You have a string of decimal digits s. Let’s define bij = si·sj. Find in matrix b the number of such rectangles that the sum bij for all cells (i, j) that are the elements of the rectangle equals a in each rectangle.

A rectangle in a matrix is a group of four integers (x, y, z, t) (x ≤ y, z ≤ t). The elements of the rectangle are all cells (i, j) such that x ≤ i ≤ y, z ≤ j ≤ t.

Input
The first line contains integer a (0 ≤ a ≤ 109), the second line contains a string of decimal integers s (1 ≤ |s| ≤ 4000).

Output
Print a single integer — the answer to a problem.

Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Sample test(s)
input
10
12345
output
6
input
16
439873893693495623498263984765
output
40
这题很简单的其实。就是一行n个数,然后构造n*n的矩阵,aij=si*sj;然后用一个矩形框起来,使矩形内的数字和为a,问有多少个这样的矩形。其实画一画矩阵就会发现,每一行都是成比例的,对,就是si乘以原来的n个数,而矩形是连续的,意思就是长和宽都是原来连续的子列和。sum=(si+……sj)*(sx+……+sy);那么把这n个数所有子列都列出来,计数,再把a分解,a=a1*a2;那么这个分解对应的矩形个数就是a1的个数乘以a2的个数。注意a=0的情况,会有所不同。因为循环是有次数极限的,即这个数或者就是36000=9*4000.但是0比较特殊。直接推导公式就好了。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char c[4050];
long long leap[40000];
int main()
{
    long long i, j, m, n, ans, k;
    long long a, pre, sum;
    memset(leap, 0, sizeof(leap));
    cin >> a;
    scanf("%s", c);
    int len = strlen(c);
    for (i = 1; i <= len; i++)
    {
        sum = 0;
        for (j = 0; j < i; j++)
        {
            sum = sum + c[j] - '0';
        }
        leap[sum]++;
        k = 0;
        for (j = i; j < len; j++)
        {
            sum = sum - (c[k] - '0');
            k++;
            sum = sum + c[j] - '0';
            leap[sum]++;
        }
    }
    sum = 0;
    if (a>36000)
        pre = 36000;
    else
        pre = a;
    for (i = 1; i <= pre; i++)
    {
        if (a%i == 0 && a/i<=36000)
        {
            if (leap[a / i]&&leap[i])
            {
                sum += leap[a / i] * leap[i];
            }
        }
    }
    if (a == 0)
        sum = leap[0] * len*(len + 1)  - leap[0] * leap[0];
    cout << sum << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值