• 20200721T1 【NOIP2015模拟10.22】矩形


    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

    Solution

    对于10%的数据

    O(n^6) 暴力

    对于30%的数据

    用前缀和优化 O(n^4) 

    对于100%的数据

    注意到s最大也就才4000,数字为0~9,前缀和最大为4000*9=36000

    令c[x]表示s一段和为x的个数

    因为 a = x * (a / x)

    则 x 和 (a / x) 都为 a 的约数且为整数

    把 c[x] 和 c[a / x] 乘起来累加

    注意特判 a = 0 的情况

    比赛时漏了。。

    code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<queue>
     7 #include<vector>
     8 #include<stack>
     9 #include<set>
    10 #include<deque>
    11 #include<map>
    12 using namespace std;
    13 
    14 template <typename T> void read(T &x) {
    15     x = 0; int f = 1; char c;
    16     for (c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') f = -f;
    17     for (; c >= '0' && c <= '9'; c = getchar()) x = 10 * x + c - '0' ;
    18     x *= f;
    19 }
    20 template <typename T> void write(T x){
    21     if (x < 0) putchar('-'), x = -x;
    22     if (x > 9) write(x / 10);
    23     putchar(x % 10 + '0');
    24 }
    25 template <typename T> void writeln(T x) { write(x); putchar('
    '); }
    26 template <typename T> void writesn(T x) { write(x); putchar(' '); }
    27 
    28 #define int long long
    29 #define inf 1234567890
    30 #define next net
    31 #define P 1000000007
    32 #define N 4005
    33 #define mid ((l+r)>>1)
    34 #define lson (o<<1)
    35 #define rson (o<<1|1)
    36 #define R register
    37 
    38 int n,goal,ans;
    39 int a[N],b[N],c[40010];
    40 char s[N];
    41 signed main(){
    42     read(goal);
    43     scanf("%s",s+1);
    44     n=strlen(s+1);
    45     for(R int i=1;i<=n;i++)a[i]=s[i]-'0',b[i]=b[i-1]+a[i];
    46     for(R int i=1;i<=n;i++)
    47         for(R int j=0;j<i;j++)
    48             c[b[i]-b[j]]++;
    49     if(goal==0){
    50         for(R int i=0;i<=40000;i++)ans+=c[0]*c[i];
    51         ans<<=1;ans-=c[0]*c[0];
    52         writeln(ans);
    53         return 0;
    54     }
    55     for(R int i=1;i<=40000;i++){
    56         if(goal%i==0&&i*40000>=goal){
    57             ans+=c[i]*c[goal/i];
    58         }
    59     }
    60     writeln(ans);
    61     return 0;
    62 }
  • 相关阅读:
    狡猾的商人
    差分约束系统
    【模板】负环
    关于Java8的精心总结
    rabbitmq+sleuth+zinkip 分布式链路追踪
    Linux下一只五颜六色的「猫」
    整理 Linux下列出目录内容的命令
    从封装变化的角度看设计模式——组件协作
    从封装变化的角度看设计模式——接口隔离
    从封装变化的角度看设计模式——对象创建
  • 原文地址:https://www.cnblogs.com/e-e-thinker/p/13353746.html
Copyright © 2020-2023  润新知