map_计蒜客T1271 完美K倍子数组

map_计蒜客T1271 完美K倍子数组

题目大意

寻找数组中任意两个两个数之和是 k 的倍数的最长完美子数组B

选出最少 2 个数,满足 他们相加其和是K的倍数,找到满足条件的一组;

解题思路

如果存在B,有两种情况:

  • 它们都是K的倍数,对K取余为0,或者余数为K/2的数字的数量大于等于2
  • 任意两个数对K取余数,它们的余数相加是K的倍数,那么数组B的长度为2

如果不存在B,输出 -1

  1. 遍历数组,用map记录每个数字模 k 的余数出现次数;同时实时检查是否存在余数互补的情况,标记f=1
  2. 统计余数为 0和(k为 偶数时)余数是 k/2 的个数
  3. 判断:
    • 如果余数 0 数量≥2 或者 余数 k/2 数量≥2 → 输出该数量
    • 否则如果存在普通互补余数对 → 输出 2
    • 全都不满足 → 输出 - 1
样例输入
复制代码
5 3  
1 3 2 3 6
样例输出
复制代码
3

完整代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long 
signed main(){
    int n,k;
    cin>>n>>k;
    // mp[余数] = 该余数出现的数字个数
    map<int,int>mp;
    int a;
    // f标记:是否找到一对余数s 和 k-s(s≠0,s≠k/2)
    int f=0;

    for(int i=0;i<n;i++){
        cin>>a;
        int s=a%k;       // 求当前数字模k的余数                                                    
        mp[s]++;         // 余数计数+1       
        if(f==0){        // 还没找到配对时才判断
            // 寻找互补余数 k-s
            if(mp[k-s]!=0){
                f=1;
            }
        }
    }

    int ans1=mp[0];          // 余数0的数字:任意两个相加都是k倍数
    int ans2=0;
    if(k%2==0){
        ans2=mp[k/2];       // k偶数时,余数k/2两个相加 = k
    }
    // 候选最大值:最多的一类特殊余数数量
    int ans=max(ans1,ans2);

    if(ans>=2)
        cout<<ans;                 // 存在≥2个余数0 或 ≥2个余数k/2,直接输出数量
    else if(f==1){
        cout<<2;                   // 存在一对 s 和 k-s,输出2
    }
    else
        cout<<-1;                  // 没有任何满足条件的数对
    return 0;
}
相关推荐
编程圈子1 小时前
电机驱动开发学习19. 霍尔 BLDC 三段式 FOC 启动算法
驱动开发·学习·算法
Hello_Damon_Nikola2 小时前
伺服电机堵转检测算法详解
单片机·嵌入式硬件·算法
罗小罗同学2 小时前
安德森癌症中心发表SCOPE IO模型,实现了对罕见肿瘤帕博利珠单抗疗效的精准预测,在患者早期即可预判药效
人工智能·算法·医学图像处理·医学ai
王维同学2 小时前
IFEO Debugger、VerifierDlls 与 SilentProcessExit 配置
c++·windows·安全·注册表
变量未定义~2 小时前
Tarjan算法-强连通分量、路径、出差
算法
geovindu2 小时前
CSharp: Iterative Algorithms
开发语言·后端·算法·c#·.net·迭代算法
小保CPP2 小时前
OpenCV C++计算多边形的最大内切圆
c++·人工智能·opencv·计算机视觉
道影子3 小时前
《黄帝内经》021章|津凝精晶 沉降为患
人工智能·深度学习·神经网络·算法·机器学习
道影子3 小时前
《黄帝内经》022章|调和双旋 伏风自消
人工智能·深度学习·神经网络·算法·机器学习