思路题,子矩阵codeforces 364 A. Matrix


       题址:  http://codeforces.com/problemset/problem/364/A
                                A. Matrix
                    time limit per test
1 second
                    memory limit per test
256 megabytes
                    input
standard input
                    output
standard output

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 thatx ≤ 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 cincout streams or the%I64d specifier.

Examples
input
          
          
10
12345
output
6
input
          
          
16
439873893693495623498263984765
output
40


题意:根据bij = si·sj把b矩阵想出来
1  2   3   4   5
2  4   6   8   10 
3  6   9  12 15
4  8  12 16 20
5 10 15 20 25
例如子矩阵4 6 8
                6 9 12
                8 12 16  的和2*(2+3+4)+3*(2+3+4)+4*(2+3+4)=(2+3+4)*(2+3+4)
求有多少个子矩阵的和等于a;
思路: 例如矩阵( bij,bxy )用(si+s(i+1)+''''+sx)*(sj+s(j+1)+''''+sy)表示矩阵的值;
把所有子串和  和个数用数组存下来,因为字符串长度4000,每一个最多是9,所以总和最多是36000.  int d【40000】,用d【i】表示子串和为 i 的有多少个,
若a是16,所以只有1*16,2*8,4*4可以。前两个不相等所以要*2(因为对称)。因为4==4所以不需要乘2。所以总个数是
d[1]*d[16]*2+d[2]*d[8]*2+d[4]*d[4];
难点;a==0这个地方真的很难处理,试了很长时间也没AC,参考了别人的博客才知道怎么处理0.0    看代码吧
m ap换成数组也可以的。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<string>
#define LL long long
using namespace std;
int a[4005];
map<int,LL>ma;
char p[4005];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",p);
    int lp=strlen(p);
    for(int i=0;i<lp;i++)
        a[i]=p[i]-'0';
        int sum=0;
    for(int i=0;i<lp;i++)
    {
        sum=0;
        for(int j=i;j<lp;j++)
        {
            sum+=a[j];
            ma[sum]++;
        }
    }
    if(n==0)
    {
        LL ans1=0;
        for(int i=1;i<50000;i++)
            ans1+=ma[0]*ma[i]*2;
        ans1+=ma[0]*ma[0];
        printf("%I64d\n",ans1);
        return 0;
    }
    LL ans=0;
    int u=sqrt(n);
    for(int i=1;i<=u;i++)
        if(n%i==0)
            ans+=ma[i]*ma[n/i];
    ans*=2;
    if(u*u==n)
        ans-=ma[u]*ma[u];
    printf("%I64d\n",ans);
    return 0;
}
这题做了5.5小时才AC,是道好题。

                                      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值