USACO 2021 January Contest, BronzeProblem 2. Even More Odd Photos题解

题目描述

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。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值