Codeforces-1582: A Luntik and Concerts
题目
题目传送门:A Luntik and Concerts
题目截图
样例描述
题目大意
有一些曲子,每个曲子可能时长 1 , 2 , 3 1, 2, 3 1,2,3,对应时长的曲子分别有 a 、 b 、 c a、b、c a、b、c ( a 、 b 、 c > 1 a、b、c > 1 a、b、c>1)首。现要将它们分为两组,求两组曲子最小的总时长之差。
题目解析
尽管这是个非常简单的问题,但非常经典。设
a
+
2
b
+
3
c
=
S
a+2b+3c=S
a+2b+3c=S,那么实际上,我们可以用
a
t
+
2
b
t
+
3
b
t
a_t+2b_t+3b_t
at+2bt+3bt (
0
≤
a
t
≤
a
0\le a_t \le a
0≤at≤a;
b
t
、
c
t
b_t、c_t
bt、ct定义类似)去表示
0
⋯
S
0 \cdots S
0⋯S 间的任意一个数。因此,如果
S
S
S 是偶数,我们均匀分配;如果
S
S
S 是奇数,那么差就是
1
1
1 。
事实上,这种能组合出和以内的任意数的问题经常常见。一般可以从取模及二进制的角度出发。对于本题,从取模角度出发,我们假设我们想要
0
⋯
S
0 \cdots S
0⋯S 间的数
k
k
k,首先我们可以用
S
S
S 最大程度地减去
t
t
t 个
3
3
3 (
S
−
3
t
≥
k
S - 3t\ge k
S−3t≥k),显然如果得到的值不是
k
k
k 的话,那么余项肯定小于
3
3
3 ,再最大程度地减去
2
2
2,如果还是不等,则余项肯定小于
2
2
2,也就必然是
1
1
1, 由于题目给出至少有
1
1
1 个
a
、
b
a、b
a、b,因此我们可以组合出
0
⋯
S
0 \cdots S
0⋯S 的所有数。这种贪心式地分析可以扩展到很多更复杂的情况。
Code
#include <bits/stdc++.h>
using namespace std;
int main(){
int t, a, b, c; string s;
cin >> t;
while(t--) {
cin >> a >> b >> c;
cout << (a + c) % 2 << endl;
}
return 0;
}