链接:https://ac.nowcoder.com/acm/contest/10746/J
来源:牛客网
题目描述
给出n数字,对于这些数字是否存在一种计算顺序,使得计算过程中数字不会超过3也不会小于0?
输入描述
首行给出一个正整数
t
,
(
1
≤
t
≤
1000
)
t,(1 \le t \le 1000)
t,(1≤t≤1000)代表测试数据组数
每组测试数据第一行一个正整数
n
,
(
1
≤
n
≤
500
)
n,(1 \le n \le 500)
n,(1≤n≤500)
第二行包含
n
n
n个以空格分隔的数字
输入保证每一个数字都是
−
3
,
−
2
,
−
1
,
+
0
,
+
1
,
+
2
,
+
3
−3, −2, −1, +0, +1, +2, +3
−3,−2,−1,+0,+1,+2,+3 的其中一个。
输出描述
每组测试数据输出一行,“Yes” or “No”
样例输入
2
4
+3 +2 -1 -2
5
+3 +2 +1 +0 +2
样例输出
Yes
No
解题思路
贪心,先考虑
−
3
-3
−3,依次判断能否让
+
3
+3
+3 或
+
2
−
1
+
2
+2 -1 +2
+2−1+2 或
+
2
+
1
+2 +1
+2+1 或
+
1
+
1
+
1
+1 +1 +1
+1+1+1 把它中和掉,直到没有
−
3
-3
−3 为止;若在中途没有东西能够中和
−
3
-3
−3,则“NO”;
然后考虑
+
3
+3
+3,当
+
3
+3
+3 的个数大于1时,依次判断能否让
−
3
-3
−3 或
−
2
+
1
−
2
-2 +1 -2
−2+1−2 或
−
2
−
1
-2 -1
−2−1 或
−
1
−
1
−
1
-1 -1 -1
−1−1−1 把它中和,直到
+
3
+3
+3 个数小于等于1为止;若在中途没有东西能够中和
+
3
+3
+3,则“NO”;
若都没有“NO”,则“YES”。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int T, n, a[7], *cnt;
bool check() {
int t = 0;
for (int i = -3; i <= 3; i++) {
t += i * cnt[i];
}
if (t > 3 || t < 0) return false;
//for -3, +3 || +2 +2 -1 || +2 +1 || +1 +1 +1
t = min(cnt[-3], cnt[3]);
cnt[-3] -= t;
cnt[3] -= t;
t = min(cnt[2], cnt[-1]);
cnt[2] -= t;
cnt[-1] -= t;
cnt[1] += t;
t = min(cnt[-3], cnt[1]);
cnt[-3] -= t;
cnt[1] -= t;
cnt[-2] += t;
if (cnt[-3] > 0) return false;
// for 3, -3 || -2 -2 +1 || -2 -1 || -1 -1 -1
t = min(cnt[-2], cnt[1]);
cnt[-2] -= t;
cnt[1] -= t;
cnt[-1] += t;
t = min(cnt[3], cnt[-1]);
cnt[3] -= t;
cnt[-1] -= t;
cnt[2] += t;
if (cnt[3] > 1) return false;
return true;
}
int main() {
//freopen("排列算式.in", "r", stdin);
scanf("%d", &T);
cnt = &a[3];
while (T--) {
memset(a, 0, sizeof(a));
scanf("%d", &n);
int t;
for (int i = 1; i <= n; i++) {
scanf("%d", &t);
cnt[t]++;
}
if (check()) {
printf("Yes\n");
} else {
printf("No\n");
}
}
return 0;
}