Link
洛谷 & Codeforces
Tag
洛谷:暂无标签
Codeforces:combinatorics,greedy,math
Difficulty Level
洛谷: 暂无评定 \color{grey}{暂无评定} 暂无评定
Codeforces: 1100 \color{grey}{1100} 1100
Solution
首先考虑满足条件的
m
m
m 的最大值,显然,让字符串按照
a
a
a 个 A
,
b
b
b 个 B
,
c
c
c 个 C
依次排列时
m
m
m 最大,为
a
−
1
+
b
−
1
+
c
−
1
=
a
+
b
+
c
−
3
a-1+b-1+c-1=a+b+c-3
a−1+b−1+c−1=a+b+c−3。
然后考虑 m m m 的最小值,不妨设 a ≤ b ≤ c a \leq b \leq c a≤b≤c,则 m m m 最小的情况为:
C A C A C A C B C B C B C B C C C . . . CACACACBCBCBCBCCC... CACACACBCBCBCBCCC...
可以得到此时 m m m 为 c − a − b − 1 c-a-b-1 c−a−b−1,这个数算出来有可能为负数,即表示 m m m 最小值为 0 0 0。
最后我们考虑从最小值到最大值之间的每个
m
m
m 是否都可以取到。我们从
m
m
m 最小时的字符串开始,从左往右依次取字符,若取到 C
就将其加入到最后面的一连串 C
中,若取到的第一个 A
将其移到最后,之后取到 A
就将其加入最后面连续的 A
中,B
与 A
同理。
例如, m m m 最小时的字符串如下:
C A C A C A C B C B C B C C C CACACACBCBCBCCC CACACACBCBCBCCC
依次转化如下:
A C A C A C B C B C B C C C C ACACACBCBCBCCCC ACACACBCBCBCCCC
C A C A C B C B C B C C C C A CACACBCBCBCCCCA CACACBCBCBCCCCA
A C A C B C B C B C C C C C A ACACBCBCBCCCCCA ACACBCBCBCCCCCA
C A C B C B C B C C C C C A A CACBCBCBCCCCCAA CACBCBCBCCCCCAA
A C B C B C B C C C C C C A A ACBCBCBCCCCCCAA ACBCBCBCCCCCCAA
C B C B C B C C C C C C A A A CBCBCBCCCCCCAAA CBCBCBCCCCCCAAA
B C B C B C C C C C C C A A A BCBCBCCCCCCCAAA BCBCBCCCCCCCAAA
C B C B C C C C C C C A A A B CBCBCCCCCCCAAAB CBCBCCCCCCCAAAB
B C B C C C C C C C C A A A B BCBCCCCCCCCAAAB BCBCCCCCCCCAAAB
C B C C C C C C C C A A A B B CBCCCCCCCCAAABB CBCCCCCCCCAAABB
B C C C C C C C C C A A A B B BCCCCCCCCCAAABB BCCCCCCCCCAAABB
C C C C C C C C C A A A B B B CCCCCCCCCAAABBB CCCCCCCCCAAABBB
显然,每次可以使得 m m m 增加 1 1 1,最终到达最大值。
所以,若 c − a − b − 1 ≤ m ≤ a + b + c − 3 c-a-b-1 \leq m \leq a+b+c-3 c−a−b−1≤m≤a+b+c−3 则 m m m 合法,否则不合法。
Code
#include<iostream>
#include<cstdio>
using namespace std;
int a,b,c,m;
void work()
{
scanf("%d%d%d%d",&a,&b,&c,&m);
if(m>a+b+c-3)
{
printf("NO\n");
return;
}
if(a>c)
swap(a,c);
if(b>c)
swap(b,c);
if(m<c-a-b-1)
{
printf("NO\n");
return;
}
printf("YES\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
work();
return 0;
}