数字(number)

题目描述
LYK收到了n个数字作为新年礼物,第i个数字的值为ai。
除了这些数字,还有一个信封,上面写着:“如果你能从这n个数中选出k个数使得它们的和为奇数,那么我将会满足你一个愿望!”
LYK觉得这不可能,此处必有玄机,于是它想在满足信封里的要求的情况下满足选出的数字的和最大。LYK想知道最大是多少。
当然不止这一年LYK收到了礼物,以后的每一年都会有这样的一个礼物,具体的,总共有m年。神奇的是这些数字并没有发生变化,而k发生了变化,LYK想知道所有年的答案是多少。
可能会存在写信人在骗它,也就是说不存在一个可行的方案,此时输出-1就可以了。

输入格式(number.in)
第一行一个数n表示LYK收到的数字个数。
第二行n个数ai表示每个数字。
第三行一个数m。
第四行m个数表示每一年的k值。

输出格式(number.out)
m行,每行输出一个答案。

输入样例
3
1 2 2
3
1 2 3

输出样例
1
3
5

数据范围
对于30%的数据n,m<=100。
对于60%的数据n,m<=1000。
对于另外10%的数据所有ai均为奇数。
对于再另外10%的数据所有ai均为偶数。
对于90%的数据n,m<=100000。
对于100%的数据n,m<=1000000,1<=ai<=n+2。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
int a[1000],qj[1000],qo[1000],hj[1000],ho[1000],s[1000],ans[1000];
int my_comp(int a,int b)
{
    if(a>b) return 1;
    return 0;
}
int main()
{ 
 int n,i,j,k,m;

 scanf("%d",&n);

 for(i=1;i<=n;i++)
  scanf("%d",&a[i]);

 sort(a+1,a+n+1,my_comp);//降序排序


 for(i=1;i<=n;i++)
  {
    if (a[i]%2==0) qo[i]=i; else qo[i]=qo[i-1];//1——i中最大的偶数
    if (a[i]%2==1) qj[i]=i; else qj[i]=qj[i-1];//1——i中最大的奇数
    s[i]=s[i-1]+a[i]; 
  }
 for(i=n;i>=1;i--)
 {
    if (a[i]%2==0) ho[i]=i; else ho[i]=ho[i+1];//i——n中最小的偶数
    if (a[i]%2==1) hj[i]=i; else hj[i]=hj[i+1];//i——n中最小的奇数
 }

 scanf("%d",&m);

 for(i=1;i<=n;i++)
 {
    ans[i]=-1;//如果无法找到解就输出-1
    if (s[i]%2==1) ans[i]=s[i]; 
    else
    {
     if (qj[i] && ho[i+1]) ans[i]=max(ans[i],s[i]-a[qj[i]]+a[ho[i+1]]);
     if (qo[i] && hj[i+1]) ans[i]=max(ans[i],s[i]-a[qo[i]]+a[hj[i+1]]);//寻找最优解
    }
 }

 for(i=1;i<=m;i++)
 {
    scanf("%d",&k);

    printf("%d
",ans[k]);//反正我不会读入输出优化
 }
 return 0;
}
原文地址:https://www.cnblogs.com/ht008/p/6819851.html