【排列组合、思维】Combinatorics Homework

一、前言

CF经典折磨…如果没能想到结论的话就是疯狂的折磨,没有尽头的那种.这种题目也只能通过不断写写CF来长长见识了.一边写一边庆幸自己没打这场Div2,否则是真的太自闭了。

二、题面讲解

Combinatorics Homework

先放出英文题面吧

You are given four integer values a, b, c and m.

Check if there exists a string that contains:

a letters 'A';
b letters 'B';
c letters 'C';
no other letters;
exactly m pairs of adjacent equal letters (exactly m such positions i that the i-th letter is equal to the (i+1)-th one).
Input
The first line contains a single integer t (1≤t≤104) — the number of testcases.

Each of the next t lines contains the description of the testcase — four integers a, b, c and m (1≤a,b,c≤108; 0≤m≤108).

Output
For each testcase print "YES" if there exists a string that satisfies all the requirements. Print "NO" if there are no such strings.

You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

Example
inputCopy
3
2 2 1 0
1 1 1 1
1 2 3 2
outputCopy
YES
NO
YES
Note
In the first testcase strings "ABCAB" or "BCABA" satisfy the requirements. There exist other possible strings.

In the second testcase there's no way to put adjacent equal letters if there's no letter that appears at least twice.

In the third testcase string "CABBCC" satisfies the requirements. There exist other possible strings.

简单的翻译一下题意:

1.输入四个数字abcm,分别代表目标字符串中’a’、‘b’、'c’的数量与相邻字符相同的组数

2.输入一组数据,询问你能不能用这些数量的’a’、‘b’、‘c’,来拼出一个相邻字符组数为m的字符串,如果可以就输出yes,反之输出no

三、题目与代码分析

直接贴上代码吧…先看看代码再来解释解释

//#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef  pair<int, int> PII;
const int N = 1e6 + 7;

int t;
int qu;
int coun[4],m;

void solve()
{
	cin >> t;
	while (t--)
	{
		bool ch = 1;
		cin >> coun[1] >> coun[2] >> coun[3] >> m;
		sort(coun + 1, coun + 4);
		if (coun[3] + coun[2] + coun[1] - 3 < m || coun[3] - coun[2] - coun[1] - 1 > m)
			cout << "NO" << endl;
		else
			cout << "YES" << endl;
	}
}

int main()
{
	solve();
	return 0;
}


想理解代码实际上只要理解一句就可以了,就是if (coun[3] + coun[2] + coun[1] - 3 < m || coun[3] - coun[2] - coun[1] - 1 > m)

拆开来看看,分别解释一下

  • coun[3] + coun[2] + coun[1] - 3 < m 这里要了解这一点,如果字母a的数量为x,那么我们最多能得到x-1组相邻字符相等的组数。如aaaaa,我们能得到4对。那么我们只要把a b c字符的数量相加减去3,就能得到字符串能够得到的最大邻字符相等的组数。然后我们就可以发现,如果我们能达到的最大数量也要小于m,那么我们自然就不可能得到邻字符相等的m组,因此输出“NO”
  • coun[3] - coun[2] - coun[1] - 1 > m简单分析一下可以发现:如果abc中某个字符的数量大于另外两者之和,我们就会不可避免的出现多组相邻字符相等。公式中所表示的结果就是尽量不出现相邻字符相等的情况的最小数量

搞懂了公式的定义后那么就不难理解代码的意思了,如果m的值在最大数量与最小数量之间,那我们就可以得到符合要求的字符串。反之则不能得到。

留下了菜鸟的泪水

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值