• four


    7月10日

    sequence|sequence.in|sequence.out

    题目描述:

    给定一个整数K和长为N的数列{Ai},求有多少个子串(不含空串)的和为K的倍数。(在这里子串表示{A[i]..A[j]},i<=j)

    输入格式:

    共两行

    第一行 两个整数N,K

    第二行 N个整数表示数列{Ai}

    输出格式:

    一行一个整数 表示满足条件的子串的个数

    样例输入:

    6 3

    1 2 6 3 7 4

    样例输出:

    7

    数据范围:

    20%    N<=100

    对另外20%  K<=100

    对所有数据  N<=500000  K<=500000

    保证输入数据中所有数都能用longint保存

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define PROC "sequence"
    using namespace std;
    const int MAXN = 500000+5;
    int x,n,k;
    int a[MAXN],rest[MAXN];
    long long ans = 0;
    int main()
    {
        scanf("%d%d",&n,&k);
        a[0] = 0;
            for (int i = 1;i<=n;i++)
         {
                           scanf("%d",&x);
                           int yushu = (x % k+k) %k;
                           a[i] = (yushu + a[i-1]%k+k) % k;
             }
             for (int i = 1;i<=n;i++)
              rest[a[i]]++;
             ans += rest[0];
         long long t;
             for (int i = 0;i<k;i++)
                     if (rest[i]!=0 && rest[i]!=1)
                     {
                      t = rest[i];
                      ans += (t * (t-1)/2);
                     }
             cout<<ans;
            return 0;
    }

    错因:

    1.正解:余数 前缀和组合

    做:反应较快 5分钟

    改:没有注意到500000的平方会超longint

    得:注意数据规模 especially 负数 和 计算过程中产生的大数据

    2.未完待续

    3.未完待续

    s��ln�/ `��le='font-size:10.5pt;font-family:"Courier New";color:darkred;mso-ansi-language: FR'>()

    {
            
            scanf("%d",&n);
            for (int i = 1; i<=n; i++)
            scanf("%d",&b[i]);
        sort(b+1,b+n+1);
        int count = 0,now = b[1];
        a[++count] = now;
        int ans = 0;
            for (int i = 2;i<=n;i++)
            {
         if (b[i]!= now) {
                           now = b[i];
                           a[++count] = now;
         }
         else ans ++;
        }
         int max = a[1];
         memset(dp, 0x3f3f,sizeof(dp));
         for (int i = 1;i<=count;i++)
         {
            dp[a[i]] = 1;
            if (a[i]>max)  max = a[i];
             }
             for (int i = 1;i<=count;i++)
              for (int j = 1;j<=max;j++)
               {
                           int cur = gcd(a[i],j);
                           if (dp[cur]>dp[j]+1) dp[cur] = dp[j] + 1;
               }
            int g = a[1];
            for (int i =2;i<=count;i++)
              g = gcd(g,a[i]);
            printf("%d",count-dp[g]+ans);
            return 0;
    }

    错因:

    1.正解:DP: dp[i]表示使得最大公约数是i最小使用多少数。

                 对于每个i枚举所有数,进行更新。

    理由:1.gcd满足“交换律结合律”。

          2. 更新结果与搜索顺序无关。

    做:审题:误把gcd当成了最大公因数。

    改:no problem

    得:缜密审题  动态思维

    2.未完待续

    3.未完待续

  • 相关阅读:
    Pivot Table 实现详解(一)
    VSTS 离线源码版本辅助工具
    早上发现还是问题不断
    VSTS 离线源码版本辅助工具源码
    C#单元测试
    长沙招聘若干 ASP.NET 开发人员(长期有效)
    解析判定数据有效性表达式的存储过程 for SQLServer
    提高 SNAP 网页预览图的采集速度
    用了2年多快3年的老ASUS本子出了点小问题了
    模拟一下细胞的繁殖(CSDN号召帖)
  • 原文地址:https://www.cnblogs.com/rubylan/p/3836801.html
Copyright © 2020-2023  润新知