蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!
Hello, 大家好哇!本初中生蒟蒻讲解一下AtCoder Regular Contest 157这场比赛的A-B题!
===========================================================================================
A题——XXYYX
原题
Problem Statement
Determine whether there is a string
S
S
S of length
N
N
N consisting of X
and Y
that satisfies the following condition.
Condition: Among the
(
N
−
1
)
(N - 1)
(N−1) pairs of consecutive characters in
S
S
S,
exactly
A
A
A are XX
,
exactly
B
B
B are XY
,
exactly
C
C
C are YX
, and
exactly
D
D
D are YY
.
Constraints
1
≤
N
≤
2
×
1
0
5
1 \leq N \leq 2 \times 10^5
1≤N≤2×105
A
≥
0
A \geq 0
A≥0
B
≥
0
B \geq 0
B≥0
C
≥
0
C \geq 0
C≥0
D
≥
0
D \geq 0
D≥0
A
+
B
+
C
+
D
=
N
−
1
A + B + C + D = N - 1
A+B+C+D=N−1
Input
The input is given from Standard Input in the following format:
N
N
N
A
A
A
B
B
B
C
C
C
D
D
D
Output
If there is a string
S
S
S that satisfies the condition, print Yes
; otherwise, print No
.
Sample Input 1
5 1 1 1 1
Sample Output 1
Yes
For instance, if S = XXYYX
, the pairs of consecutive characters are XX
, XY
, YY
, and YX
from left to right. Each pattern occurs exactly once, so the condition is satisfied.
Sample Input 2
5 1 2 1 0
Sample Output 2
Yes
For instance, S = XXYXY
satisfies the condition.
Sample Input 3
5 0 4 0 0
Sample Output 3
No
No string satisfies the condition.
思路
我们通过成千上万次的找规律,会发现其实XX
和YY
根本没有用,大家可以自行模拟~~~ 所以,有用的是XY
和YX
,他们俩出现的次数之差必须小于等于1,否则会匹配不起来!当然又一个特殊的情况,如果XY
和YX
出现的次数都是0,且XX
和YY
都出现过,也是不行的,要输出NO
,所以这里要特判一下~~~
代码
/*
------------------Welcome to Your Code--------------
Name:
Contest:AtCoder Regular Contest 157
Wishes:AK!
------------------Start Writing!!!------------------
*/
#include <iostream>
#define endl '\n'
#define pb(i) push_back(i)
using namespace std;
inline int read()
{
int w = 1, s = 0;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
return w * s;
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n = read(), a = read(), b = read(), c = read() , d = read();
if (abs(b - c) <= 1){ //注意要用绝对值
if(b == 0 and c == 0)//特判
if(a == n - 1 or d == n - 1)
cout << "Yes" <<endl;
else
cout << "No" <<endl;
else cout << "Yes"<<endl;
}
else
cout << "No" <<endl;
return 0;
}
B题——XYYYX
原题
Problem Statement
You are given a string
S
S
S of length
N
N
N consisting of X
and Y
.
You will choose
K
K
K characters at distinct positions in
S
S
S and change each of them: X
becomes Y
and Y
becomes X
.
Find the maximum possible number of pairs of consecutive Y
s in the resulting string.
Constraints
1
≤
N
≤
2
×
1
0
5
1 \leq N \leq 2 \times 10^5
1≤N≤2×105
0
≤
K
≤
N
0 \leq K \leq N
0≤K≤N
S
S
S is a string of length
N
N
N consisting of X
and Y
.
Input
The input is given from Standard Input in the following format:
N
N
N
K
K
K
S
S
S
Output
Print the maximum possible number of pairs of consecutive Y
s in the resulting string.
Sample Input 1
5 1
XYXYX
Sample Output 1
2
You will choose one character.
If you choose the
1
1
1-st character, the resulting string is YYXYX
, with one pair of consecutive Y
s at positions
1
,
2
1, 2
1,2.
If you choose the
2
2
2-nd character, the resulting string is XXXYX
, with no pair of consecutive Y
s.
If you choose the
3
3
3-rd character, the resulting string is XYYYX
, with two pairs of consecutive Y
s at positions
2
,
3
2, 3
2,3 and
3
,
4
3, 4
3,4.
If you choose the
4
4
4-th character, the resulting string is XYXXX
, with no pair of consecutive Y
s.
If you choose the
5
5
5-th character, the resulting string is XYXYY
, with one pair of consecutive Y
s at positions
4
,
5
4, 5
4,5.
Thus, the sought maximum number is
2
2
2.
Sample Input 2
5 4
XYXYX
Sample Output 2
2
It is optimal to choose the
1
1
1-st,
2
2
2-nd,
3
3
3-rd, and
5
5
5-th characters to get YXYYY
, or choose the
1
1
1-st,
3
3
3-rd,
4
4
4-th, and
5
5
5-th characters to get YYYXY
.
Note that you may not choose a character at the same position multiple times.
思路
首先,通过直觉肯定是把X
变成Y
好!
我们可以发现有三种情况(设S中X
的个数为cx)
- c x = n cx = n cx=n ,则输出 m a x ( k − 1 , 0 ) max(k - 1, 0) max(k−1,0)
-
k
≤
c
x
k \leq cx
k≤cx,此时分为了三步
- 将
YXXX…XXXY
中的所有X
变成Y
,此时会在原基础的YY
个数上多一个! - 将
Y
旁边剩余不足 K K K个的X
变成Y
,此时会多一个YY
- 若S中有本来就有
YY
,那么加上原来就有的个数
- 将
-
k
>
c
x
k > cx
k>cx,那么我们可以转换一下,其实就是把S中
X
变成Y
,Y
变成X
,然后此时是选 n − k n - k n−k个X
,此时转换为了上文的 k ≤ c x k \leq cx k≤cx的情况
代码
/*
------------------Welcome to Your Code--------------
Name:
Contest:
Wishes:AK!
------------------Start Writing!!!------------------
*/
#include <iostream>
#define endl '\n'
#define pb(i) push_back(i)
using namespace std;
const int N = 2e5 + 10;
int n, k, res;
string s;
int pos[N], cnt;
int len[N];
inline int read()
{
int w = 1, s = 0;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
return w * s;
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n >> k >> s;
int cx = 0;
s = ' ' + s;
for (int i = 1; i <= n; i ++) //记录Y的位置
if (s[i] == 'Y')
pos[++ cnt] = i;
else //记录X的个数
cx ++;
if (k > cx) //转换
{
cx = cnt = 0;
for (int i = 1; i <= n; i ++)
s[i] = (s[i] == 'X') ? 'Y' : 'X';
for (int i = 1; i <= n; i ++)
if (s[i] == 'X')
cx ++;
else pos[++ cnt] = i;
k = n - k;
}
if (cx == n) //直接输出
{
cout << max(k - 1, 0) << endl;
return 0;
}
for (int i = 1; i < cnt; i ++) //记录YXX...XXY情况中X..X的个数的序列所出现的次数
len[pos[i + 1] - pos[i] - 1] ++;
for (int i = 1; i <= n && k; i ++) //通过贪心的思想,肯定是先找短的,这样多的那1个YY就能更快的得到
while (len[i] && k)
if (i <= k) //说明能把其中的X全变成Y
res += i + 1, k -= i, len[i] --;
else //只能变K个
res += k, k = 0;
if (k) res += k; //K还有剩余,全部变
for (int i = 1; i < cnt; i ++) //若本来就有相邻的YY,记录上
if (pos[i + 1] - pos[i] == 1)
res ++;
cout << res << endl; //输出结果
return 0;
}
今天就到这里了!
大家有什么问题尽管提,我都会尽力回答的!
吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!