zoukankan      html  css  js  c++  java
  • 试题 历届试题 倍数问题(思维、数学)

    传送门

     

    题解:题目是要求找到三个数之和最大并取模K等于0。

    我们可以将每个数对k取模,并记录取余k相同的数中最大三个数(vector模拟即可)

    那么我们只需要枚举这其中所有的三个余数之和结果取余k为0的方案(要防止取余结果为负),取最大和即可。

    每个数只能取一个,所以需要开几个num数组记录当前余数中最大数的下标,注意每次枚举完要恢复原先的存储。

    算法复杂度(k^2=1e6)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    const int M = 100005;
    vector<int>v[N];
    int num1[M],num2[M];
    void init(int x,int y,int z){
        num1[x]=num2[x];
        num1[y]=num2[y];
        num1[z]=num2[z];
    }
    int main(){
        int n,k,a;scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++){
            scanf("%d",&a);
            if(v[a%k].size()<3){v[a%k].push_back(a);}
            else if(a>v[a%k][0]){v[a%k][0]=a;}
            sort(v[a%k].begin(),v[a%k].end());
        }
        for(int i=0;i<k;i++){
            num1[i]=num2[i]=v[i].size();
        }
        long long maxx=-1;
        for(int i=0;i<k;i++){
            long long ans;
            for(int j=0;j<k;j++){
                ans=0;
                int z=(k-i-j+k)%k; 
                if(num1[i]<1){init(i,j,z);continue;}
                ans+=v[i][--num1[i]];
                if(num1[j]<1){init(i,j,z);continue;}
                ans+=v[j][--num1[j]];
                if(num1[z]<1){init(i,j,z);continue;}
                ans+=v[z][--num1[z]];
                init(i,j,z);
                maxx=max(maxx,ans);
            }
        }
        cout<<maxx<<endl;
        return 0;
    } 
    /*
    10 8
    17 9 19 43 32 40 34 100 89 20
    232
    */
  • 相关阅读:
    php部分---include()与require()的区别、empty()与isset is_null的区别与用法详解
    DataSet 的详细用法(转)
    DataSet 的用法(转)
    大神的博客地址
    c#报表 柱,饼状图
    WebApi 增删改查(2)
    Linq to SQL 的左连,右连,内连(转)
    WebApi 增删改查
    Linq to SQL 的连表查询(转)
    LINQ
  • 原文地址:https://www.cnblogs.com/mohari/p/13948540.html
Copyright © 2011-2022 走看看