Acwing 4619. 减法操作 贪心

题目描述

给定一个包含 n 个非负整数的数列 a1,a2,…,an。

你可以对该数列进行以下两种减法操作:

任选其中一个元素,并将该元素的值减去 2。
任选两个相邻元素,并将两个元素的值各减去 1。
请你判断,能否经过一系列减法操作,使得数列中的所有元素都变为 0。

输入格式
第一行包含整数 n。

第二行包含 n 个非负整数 a1,a2,…,an。

输出格式
如果能够经过一系列减法操作,使得数列中的所有元素都变为 0,则输出 YES,否则输出 NO。

数据范围
前 6 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×105,0≤ai≤104。

输入样例1:
4
1 2 1 2
输出样例1:
YES
输入样例2:
3
1 0 1
输出样例2:
NO

思路:贪心

对于最终的结果来说,操作1和操作2执行的先后顺序是没有影响的。
所以我们可以,先执行操作二,看看能不能把序列中所有的数变成非负的偶数

问:想问一下大佬 执行操作二的时候 为什么可以从头到尾这么操作 
会不会存在一种奇特的顺序导致从头到尾这么执行不能输出YES
而一个别的执行顺序就可以YES?

答:因为代码中操作二的功能是将发现的奇数及它后面一个数减1,
使该奇数变为偶数,若后面的数又成为奇数,那也执行相同操作
,所以遍历结束后,奇数将会堆在最后,此时可以判断a[n]的奇偶性
,即可判断整串序列

但注意这样还需判断a序列是否均不为负数,所以我选择了以上的思路,
及遍历每一个a[i]的奇偶性,大小

参考:

acwing.com/solution/content/139118/

代码

/*
    思路:贪心
    
    对于最终的结果来说,操作1和操作2执行的先后顺序是没有影响的。
    所以我们可以,先执行操作二,看看能不能把序列中所有的数变成非负的偶数
    
    问:想问一下大佬 执行操作二的时候 为什么可以从头到尾这么操作 
    会不会存在一种奇特的顺序导致从头到尾这么执行不能输出YES
    而一个别的执行顺序就可以YES?
    
    答:因为代码中操作二的功能是将发现的奇数及它后面一个数减1,
    使该奇数变为偶数,若后面的数又成为奇数,那也执行相同操作
    ,所以遍历结束后,奇数将会堆在最后,此时可以判断a[n]的奇偶性
    ,即可判断整串序列
    
    但注意这样还需判断a序列是否均不为负数,所以我选择了以上的思路,
    及遍历每一个a[i]的奇偶性,大小
    
    参考:
    acwing.com/solution/content/139118/
*/
#include <iostream>

using namespace std;

const int N = 2000010;
int a[N];

int main() {
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    
    for (int i = 0; i < n - 1; i ++ ) {
        if(a[i] % 2 == 1) a[i] --, a[i + 1] --;
    }
    
    int s = 0;
    for (int i = 0; i < n; i ++ ) 
        s += (a[i] % 2 == 1 || a[i] < 0);
    
    if (!s) puts("YES");
    else puts("NO");
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值