题目描述
Farmer John 正再一次尝试给他的 N 头奶牛拍照(2≤N≤1000)。
每头奶牛有一个范围在 1…100 之内的整数的「品种编号」。Farmer John 对他的照片有一个十分古怪的构思:他希望将所有的奶牛分为不相交的若干组(换句话说,将每头奶牛分到恰好一组中)并将这些组排成一行,使得第一组的奶牛的品种编号之和为偶数,第二组的编号之和为奇数,以此类推,奇偶交替。
Farmer John 可以分成的最大组数是多少?
输入格式(从终端/标准输入读入):
输入的第一行包含 N。下一行包含 N 个空格分隔的整数,为 N 头奶牛的品种编号。
输出格式(输出至终端/标准输出):
输出 Farmer John 的照片中的最大组数。可以证明,至少存在一种符合要求的分组方案。
输入样例:
7 1 3 5 7 9 11 13
输出样例:
3
样例解释
在这个样例中,以下是一种分成最大组数三组的方案。将 1 和 3 分在第一组,5、7 和 9 分在第二组,11 和 13 分在第三组。
输入样例:
7 11 2 17 13 1 15 3
输出样例:
5
样例解释
在这个样例中,以下是一种分成最大组数五组的方案。将 2 分在第一组,11 分在第二组,13 和 1 分在第三组,15 分在第四组,17 和 3 分在第五组。
供题:Nick Wu
要求与思路:
1. 要求:给n个数字分组,并按照偶数、奇数、偶数、奇数...这样的顺序进行排列
2. 能够形成题目要求的偶数、奇数、偶数...这样的顺序只有两种情况,一种是偶数的组合比奇数多一个,一种是偶数的组合和奇数一样多。同时奇数可以两两结合变成偶数,但是偶数如果想变成奇数则必须结合一个奇数才可以。
3. 分类,以下用even代表偶数数字的个数,用odd代表奇数数字的个数
a, odd>even,则需要将两个奇数合并为一个偶数,直到odd<=even
b, odd==even,则可以划分为2*odd个组合
c, odd + 1 == even,则可以划分为2*odd+1个组合
d, odd < even - 1,则合并偶数,按照奇数的数量划分为2*odd+1个组合
代码
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int n;
cin >> n;
int even = 0, odd = 0;
//统计奇数、偶数数字的个数
for (int i = 1; i <= n; i++){
int tmp;
cin >> tmp;
if (tmp % 2 == 1)odd++;
else even++;
}
//根据奇数偶数个数分类处理
//奇数可以组合变成偶数,但是偶数要想变成奇数必须联合一个奇数
//同时发现,一个偶数后边跟着一个奇数,总量要么二者数量相等E+O要么偶数多一个
//所以可以平衡下Even和Odd的数量差
while(odd > even){
odd -= 2;
even++;
}
//接下来分三类
if (odd == even) cout << 2 * even;
else if (odd + 1 == even)cout << 2 * odd + 1;
else cout << 2 * odd + 1;
return 0;
}
思考:
1. 虽然代码不多,但是这个小题还是非常考验分类和分析的能力的,应该多练习一些这样的题目
2. 这里给几个例子帮助分析,odd + 1 <= even的时候比较容易分析,这里分析odd + 1 > even的情况,合并奇数之后只会得到三种情况,一种是二者相等,odd=9,even=6,合并奇数后odd=7,even=7;一种是odd + 1 == even,当odd=8,even=6,合并得到odd=6,even=7;一种是odd + 2 == even,当odd=7,even=6,合并得到odd=5,even=7。