zoukankan      html  css  js  c++  java
  • 倍数问题(2018蓝桥杯)

    题目描述:

    众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。
    但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。
    现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。

    输入格式:

    从标准输入读入数据。
    
    第一行包括 2 个正整数 n, K。
    第二行 n 个正整数,代表给定的 n 个数。

    输出格式:

    输出到标准输出。
    输出一行一个整数代表所求的和。

    示例:

    输入:
    4 3
    1 2 3 4
    
    输出:
    9

    数据约定:

    对于 30% 的数据,n <= 100。
    对于 60% 的数据,n <= 1000。
    对于另外 20% 的数据,K <= 10。
    对于 100% 的数据,1 <= n <= 10^5, 1 <= K <= 10^3,给定的 n 个数均不超过 10^8。
    
    
    资源约定:
    峰值内存消耗(含虚拟机) < 256M
    CPU消耗 < 1000ms
    
    
    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
    
    注意:
    main函数需要返回0;
    只使用ANSI C/ANSI C++ 标准;
    不要调用依赖于编译环境或操作系统的特殊函数。
    所有依赖的函数必须明确地在源文件中 #include <xxx>
    不能通过工程设置而省略常用头文件。

    题目分析:

    本题可以使用暴力枚举,枚举分析所有的数,若分析得出结果值最大值输出;

    但是若纯 暴力时间复杂度将会变得十分大,

    所以可以先分析所有数据,只保留余数相同的最大的三个数。然后逐个枚举得出结果。

     

    代码:

    c++:

    #pragma warning(disable:4996)
    #include<iostream>
    #include<memory>
    #include<vector>
    #include<unordered_map>
    typedef long long ll;
    inline int read()
    {
        int x = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch>'9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    int main()
    {
        int i, num;
        int k, flag = 1;
        int b[1001][3];//用于判断余数相同的三个数
        memset(b, -1, sizeof(b));
        std::unordered_map<int, int>c;//map的key值存放余数,value值存放余数对应二维数组b的下标
        scanf("%d %d", &i, &num);
    
    
        while (i--)
        {
            k = read();
            int kk = k % num;
            if (!c[kk])
            {
                c[k % num] = flag;//将余数所在的位置给map的映射
                b[flag][0] = k;
                flag++;
            }
            else//若该余数有值,则替换其中最小值或者加入其中
            {
                int inte = k;
                for (int z = 0;z < 3;z++)
                    if (b[c[kk]][z] < inte)
                        inte ^= b[c[kk]][z] ^= inte ^= b[c[kk]][z];
            }
        }
        //枚举
        ll ans = 0, v1, v2, v3;
        for (auto iter1 = c.begin();iter1 != c.end();iter1++)
        {
            for (auto iter2 = c.begin();iter2 != c.end();iter2++)
            {
                int mainder = (2 * num - iter1->first - iter2->first) % num;
                v1 = b[iter1->second][0];
                if (iter1->first == iter2->first)
                {
                    v2 = b[iter1->second][1];
                    if (iter1->first == mainder)
                        v3 = b[iter1->second][2];
                    else
                        v3 = b[mainder][0];
                    if (v3 == -1 || v2 == -1) continue;
                }
                else
                {
                    v2 = b[iter2->second][0];
                    if (iter1->first == mainder) v3 = b[iter1->second][1];
                    else if (iter2->first == mainder) v3 = b[iter2->second][1];
                    else v3 = b[mainder][0];
                    if (v3 == -1 || v2 == -1) continue;
                }
                ll tem = v1 + v2 + v3;
                if (ans < tem)ans = tem;
            }
        }
        printf("%lld", ans);
        return 0;
    }
     
  • 相关阅读:
    设计模式01之 简单工厂模式(创建模式)
    UML系列05之 基本流程图
    UML系列04之 UML时序图
    UML系列03之 UML类图(二)
    UML系列02之 UML类图(一)
    LaTex in Markdown
    Ubuntu18.04 下的Gif录制工具
    Python3 与 C# 扩展之~基础衍生
    Python3 与 C# 扩展之~模块专栏
    Python3 与 C# 面向对象之~异常相关
  • 原文地址:https://www.cnblogs.com/zjw1324399/p/14304463.html
Copyright © 2011-2022 走看看