• k倍区间


    用前缀和来求区间和,然后用一个二重循环穷举,但是因为问题规模为100000,所以超时(28分)

    超时代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100010
    #define MAX 0x06FFFFFF
    #define V vector<int>
    #define ll long long
    
    using namespace std;
    
    ll sum[LEN]; 
    
    int main(){
    //    freopen("D:/CbWorkspace/blue_bridge/k倍区间.txt","r",stdin);
        int i,j,n,k,ans=0;
        I("%d%d",&n,&k);
        FF(i,n){
            I("%d",&j);
            sum[i+1]=sum[i]+j;
        }
        for(i=1;i<=n;i++){
            for(j=i;j<=n;j++){
                int t=(sum[j]-sum[i-1]);
                if((sum[j]-sum[i-1])%k==0)
                    ans++;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    观看了大佬的AC代码,终于明白怎么回事了。一句话, 计算前缀和然后取余k, 如果前i项和取余k与前j项和取余k后相同,那么i到j这个区间和为k的倍数

    注意ans,cnt,sum都要开 long long

    AC代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100010
    #define MAX 0x06FFFFFF
    #define V vector<int>
    #define ll long long
    
    using namespace std;
    
    ll sum[LEN]; 
    ll cnt[LEN];
    
    int A(int n,int m){
        int a=1;
        while(m){
            a*=n--;
            m--;
        }
        return a;
    }
    
    int C(int n,int m){
        int c=A(n,m);
        while(m){
            c/=m--;
        }
        return c;
    }
    
    int main(){
    //    freopen("D:/CbWorkspace/blue_bridge/k倍区间.txt","r",stdin);
        int i,j,n,k;
        ll ans=0;
        I("%d%d",&n,&k);
        FF(i,n){
            I("%d",&j);
            sum[i+1]=sum[i]+j;
        }
        cnt[0]=1;
        F(i,1,n+1){
            cnt[sum[i]%k]++;
        }
        FF(i,k){
            if(cnt[i]) ans+=cnt[i]*(cnt[i]-1)/2;    //C(n,2)
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    C#中处理鼠标和键盘的事件
    C#中处理鼠标和键盘的事件
    C#中处理鼠标和键盘的事件
    mpich2安装
    算法题推箱子
    LINUX终端下windows盘的位置
    Linux头文件和库文件添加环境变量与GCC编译器添加INCLUDE与LIB环境变量
    第九章顺序容器重学C++之《 C++ PRIMER》
    sed中使用变量
    抛出异常
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8456397.html
Copyright © 2020-2023  润新知