一、题目
花椰妹去玩具店玩积木啦!
现在花椰妹的面前有一堵积木墙,宽度为 n 个格子,每个格子对应的高度为 ai 个格子。现在花椰妹要用 2×1 的积木来搭墙。
如果相邻两个格子的高度相同,花椰妹就可以将积木横着放,使得这两个格子的高度都加一。
当然花椰妹可以在任何情况下将积木竖着放,使得当前格子的高度加二。
现在给你 n 和所有的 ai ,请问花椰妹能不能将所有的格子的高度统一?
输入格式:
输入的第一行包含一个整数 n(2 ≤ n ≤ 2×105 )。 输入的第二行包括 n 个整数,为每个格子的初始高度 ai(2 ≤ ai ≤ 109 )。
输出格式:
对于给定的积木墙,如果可以输出“YES”,否则输出“NO”。
Inputcopy:
5
2 1 1 2 5
Outputcopy:
YES
Inputcopy:
2
10 10
Outputcopy:
YES
Inputcopy:
3
1 2 3
Outputcopy:
NO
二、方法一
1、思路
分析一下刷墙的规则:
- 任何情况下将积木竖着放,使得当前格子的高度加二:说明如果两个数的奇偶性相同,则这两个数可以相等;
- 如果相邻两个格子的高度相同,花椰妹就可以将积木横着放,使得这两个格子的高度都加一:说明如果两个数的奇偶性相同(数目可以通过竖着放改变)且相邻,则可以同时改变两个数的奇偶性。
那问题就转化为,能否使所有数据的奇偶性相同。
利用第2个规则,如果两个奇偶性相同的数中间有偶数个数,那奇偶性就可以相同,反之,则不行。
最开始我是计算两个奇偶性相同的数中间有几个数,测试样例都过了,但是没有AC,然后我又用下标标记了一下,改变了判定条件,就AC了。总的来说这个题还是有难度的。
2、代码
#include<stdio.h>
#define Max 200010
int n; // n 个格子
int i, j, k; // 遍历
int a[Max]; // 每个格子的高度
int check(int x);
int main()
{
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
if (check(1) || check(0))
printf("YES");
else
printf("NO");
return 0;
}
int check(int x)
{
int flag = 0;
for (int j = 1; j <= n; j++)
{
// 奇偶性与X相同
if ((a[j] % 2) == x)
continue;
// 第二次出现奇偶性与X不同的
if (flag != 0)
{
// 计算长度
flag = j - 1 - flag;
// 如果长度为奇数,则不能完成
if (flag % 2 == 1)
return 0;
// 该段墙刷完了,将下标置为0
flag = 0;
}
// 第一次出现奇偶性与X不同的
else
flag = j;
}
// 判断是否完全刷完,如果刷完下标应为初始值
return flag == 0;
}