更多奇怪的照片

更多奇怪的照片

Farmer John 正再一次尝试给他的 N 头奶牛拍照。

每头奶牛有一个范围在 1100 之内的整数的「品种编号」,编号可能重复。

Farmer John 对他的照片有一个十分古怪的构思:他希望将所有的奶牛分为不相交的若干组(换句话说,将每头奶牛分到恰好一组中)并将这些组排成一行,使得第一组的奶牛的品种编号之和为偶数,第二组的编号之和为奇数,以此类推,奇偶交替。

Farmer John 可以分成的最大组数是多少?

输入格式

输入的第一行包含 N

下一行包含 N 个空格分隔的整数,为 N 头奶牛的品种编号。

输出格式

输出 Farmer John 的照片中的最大组数。

可以证明,至少存在一种符合要求的分组方案。

数据范围

2N1000

输入样例1:

7
1 3 5 7 9 11 13

输出样例1:

3

样例1解释

在这个样例中,以下是一种分成最大组数三组的方案。

13 分在第一组,579 分在第二组,1113 分在第三组。

输入样例2:

7
11 2 17 13 1 15 3

输出样例2:

5

样例2解释

在这个样例中,以下是一种分成最大组数五组的方案。

2 分在第一组,11 分在第二组,131 分在第三组,15 分在第四组,173 分在第五组。

 

解题思路

  先证明一下为什么一定会有解。如果所有的数的总和是偶数,那么必然会得到一组。如果总和为奇数,意味着这些数中必然存在一个奇数,我们把这个奇数拿出来放到第二组,剩余的数(剩余的数的和是偶数)放到第一组。

  然后还可以发现,一个数加上偶数并不会改变这个数的奇偶性,一个数加上一个奇数会改变这个数的奇偶性,因此奇数可以通过相加来改变一组的奇偶性。

  我们一开始先统计一下奇数和偶数的个数,假设有a个偶数,b个奇数。每两个奇数可以通过相加得到一个偶数,意味着可以通过减少两个奇数来得到一个偶数,例如a+1, b2a+2, b4以此类推。满足要求的划分方案一定是要满足x=y或者x=y+1,即xy(关键,本题突破口)。

  如果x=y,那么总共的组数为2y

  如果x=y+1,那么总共的组数为2y+1

  如果x>y+1,由于偶数个数最多比奇数个数多1,因此我们可以把多余的偶数进行合并,得到y+1组,因此总共的组数为2y+1

  因此如果有xy,那么总组数为2y+1

  因此我们只考虑xy的情况,如果偶数的个数小于奇数的个数,我们可以通过奇数来凑出偶数,直到满足xy。(如果已经满足xy,而继续用奇数凑偶数,可以发现总组数是会减少的。)

  AC代码如下:

复制代码
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int main() {
 6     int n, a = 0, b = 0;
 7     scanf("%d", &n);
 8     while (n--) {
 9         int val;
10         scanf("%d", &val);
11         if (val & 1) a++;
12         else b++;
13     }
14     
15     while (a > b) {
16         a -= 2;
17         b++;
18     }
19     
20     printf("%d", a == b ? a * 2 : a * 2 + 1);
21     
22     return 0;
23 }
复制代码

 

参考资料

  AcWing 3359. 更多奇怪的照片(春季每日一题2022):https://www.acwing.com/video/3863/

posted @   onlyblues  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示