3 条题解

  • 4
    @ 2024-5-27 20:35:49

    你可以试试暴力枚举:

    #include <bits/stdc++.h>
    using namespace std;
    int a[100001],num[100001],n,k;
    long long ans;
    int main()
    {
        cin >> n >> k;
        for(int i=1;i<=n;i++){cin>>a[i];num[i]=a[i]+num[i-1];}
        for(int i = 1;i <= n;i++){
            for(int j = i;j <= n;j++){
                if((num[j]-num[i-1])%k == 0){
                    ans++;
                }
            }
        }
        cout << ans;
        return 0;
    }
    

    but... AC:8 WA:2 so:

    //解决这道题,要选出一个区间,要找到两个除以K余数相等的两个前缀和(因为相减得到的数字除以K等于0),所以要定义一个数组cnt,cnt[x]表示sum(前缀和)除以K的余数个数,然后对所有情况求和。
    #include <bits/stdc++.h>
    using namespace std;
    int n,k,a,sum,cnt[100005],ans;
    int main(){
        cin>>n>>k;
        cnt[0]=1;
        for(int i=1;i<=n;i++){
            cin>>a;
            sum+=a;
            sum%=k;
            ans+=cnt[sum]++;
        }
        cout<<ans;
        return 0;
    }
    

    AC:10 一个赞抱走~

    • 0
      @ 2023-12-23 17:12:30

      思路

      解决这道题,要选出一个区间,要找到两个除以K余数相等的两个前缀和(因为相减得到的数字除以K等于0),所以要定义一个数组cnt,cnt[x]表示sum(前缀和)除以K的余数个数,然后对所有情况求和。

      注意

      那些只拿70分的同学注意了!(我也被坑了十多次了)sum得到的值会非常大,很容易出错。

      代码

      核心代码
      cnt[0]=1;
      for(int i=1;i<=n;i++){
          cin>>a;
          sum+=a;
          ans+=cnt[sum%k]++;
      }
      
      参考代码
      #include <iostream>
      using namespace std;
      int main(void){
          long long n,k,a,sum=0,cnt[100005]={},ans=0;
          cin>>n>>k;
          cnt[0]=1;
          for(int i=1;i<=n;i++){
              cin>>a;
              sum+=a;
              ans+=cnt[sum%k]++;
          }
          cout<<ans;
          return 0;
      }
      
      • @ 2024-5-3 22:09:54

        你直接一边累加sum一边将sum对k求余不就行了吗?

        参考代码
        #include <bits/stdc++.h>
        using namespace std;
        int n,k,a,sum,cnt[100005],ans;
        int main(){
            cin>>n>>k;
            cnt[0]=1;
            for(int i=1;i<=n;i++){
                cin>>a;
                sum+=a;
                sum%=k;
                ans+=cnt[sum]++;
            }
            cout<<ans;
            return 0;
        }
        
    • -2
      @ 2023-11-5 20:17:00

      K的倍数即对K取余等于0。因此,找到两个对K取余的余数相等的前缀和,即可得到一个K倍区间。枚举i从1到n,用cnt[x]表示i之前的前缀和为x的数量,设1到i的前缀和为sum,i对应的区间数量即为cnt[sum%k],对所有情况求和即可。

      核心代码
      
      cnt[0] = 1;
      for (int i = 1; i <= n; i++) {
      	cin >> a;
      	sum += a;
      	ans += cnt[sum % k];
      	cnt[sum % k]++;
      }
      cout << ans;
      
      • 1

      信息

      ID
      546
      时间
      2000ms
      内存
      256MiB
      难度
      3
      标签
      (无)
      递交数
      231
      已通过
      132
      上传者