D. Colorful Stamp
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
A row of nn cells is given, all initially white. Using a stamp, you can stamp any two neighboring cells such that one becomes red and the other becomes blue. A stamp can be rotated, i.e. it can be used in both ways: as BRBR and as RBRB.
During use, the stamp must completely fit on the given nn cells (it cannot be partially outside the cells). The stamp can be applied multiple times to the same cell. Each usage of the stamp recolors both cells that are under the stamp.
For example, one possible sequence of stamps to make the picture BRBBWBRBBW could be WWWWW→WWRB–––W→BR–––RBW→BRB–––BWWWWWW→WWRB_W→BR_RBW→BRB_BW. Here WW, RR, and BB represent a white, red, or blue cell, respectively, and the cells that the stamp is used on are marked with an underline.
Given a final picture, is it possible to make it using the stamp zero or more times?
Input
The first line contains an integer tt (1≤t≤1041≤t≤104) — the number of test cases.
The first line of each test case contains an integer nn (1≤n≤1051≤n≤105) — the length of the picture.
The second line of each test case contains a string ss — the picture you need to make. It is guaranteed that the length of ss is nn and that ss only consists of the characters WW, RR, and BB, representing a white, red, or blue cell, respectively.
It is guaranteed that the sum of nn over all test cases does not exceed 105105.
Output
Output tt lines, each of which contains the answer to the corresponding test case. As an answer, output "YES" if it possible to make the picture using the stamp zero or more times, and "NO" otherwise.
You can output the answer in any case (for example, the strings "yEs", "yes", "Yes" and "YES" will be recognized as a positive answer).
Example
input
Copy
12 5 BRBBW 1 B 2 WB 2 RW 3 BRB 3 RBB 7 WWWWWWW 9 RBWBWRRBW 10 BRBRBRBRRB 12 BBBRWWRRRWBR 10 BRBRBRBRBW 5 RBWBW
output
Copy
YES NO NO NO YES YES YES NO YES NO YES NO
Note
The first test case is explained in the statement.
For the second, third, and fourth test cases, it is not possible to stamp a single cell, so the answer is "NO".
For the fifth test case, you can use the stamp as follows: WWW→WRB–––→BR–––BWWW→WRB_→BR_B.
For the sixth test case, you can use the stamp as follows: WWW→WRB–––→RB–––BWWW→WRB_→RB_B.
For the seventh test case, you don't need to use the stamp at all.
这道题我在做的时候选用了错误的方法, 首先我们来总结一下什么样的情况,
上一次w到这一次w之间, 如果他俩不相邻并且R或者W有一个出现另外一个没有出现就是错的.
所以说为了方便处理我们首先在字符串的两端加上w
然后分享一下我的做法, (本人暴力大水货一个)就先在两端加w然后判断相邻两个w之间的东西, 老暴力了, 直接tle了
再分享一下sambilion大佬的想法, 字符串前缀和, 就是
q[i] = q[i - 1];
r[i] = r[i - 1];
if (s[i] == 'B') ++ q[i];
if (s[i] == 'R') ++ r[i];
我们在找的时候用一个双指针, 用t表示上一次w出现的位置, 然后if (q[i] - q[t] == 0 || r[i] - r[t] == 0)就是错误的。
另外记得处理i是w, i - 1也是w(就是他俩靠着的这种情况)
if (s[i] == 'W' && i == t + 1) {
t = i;
continue;
}
代码奉上(第一个本人的大暴力哈哈哈)第二个陈师傅的
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
#define endl "\n"
const int N = 1e06 + 10;
int cnt[N];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int _ = 1;
cin >> _;
while (_--) {
int len;
cin >> len;
string op;
cin >> op;
memset(cnt, 0, sizeof cnt);
if (len == 1) {
if (op == "R" || op == "B") {
cout << "NO" << endl;
continue;
} else {
cout << "YES" << endl;
continue;
}
}
if (len == 2) {
if (op == "RR" || op == "BB" || op == "RW" || op == "WR" ||
op == "BW" || op == "WB") {
cout << "NO" << endl;
continue;
} else {
cout << "YES" << endl;
continue;
}
}
int num = 0;
int flag1 = 0; // W appeared ?
int flag2 = 0; // R appeared ?
int flag3 = 0; // B appeared ?
for (int i = 0; i < len; i++) {
if (op[i] == 'W') {
flag1 = 1;
cnt[num++] = i;
};
if (op[i] == 'R') flag2 = 1;
if (op[i] == 'B') flag3 = 1;
}
if ((flag2 == 0 && flag3 == 1) || (flag2 == 1 && flag3 == 0)) {
cout << "NO" << endl;
continue;
} else if (flag1 == 1 && flag2 == 1 && flag3 == 1) {
if (num == 1) {
int cnt1 = 0, cnt2 = 0; // R, B
for (int i = 0; i < cnt[0]; i++) {
if (op[i] == 'R') {
cnt1 = 1;
} else {
cnt2 = 1;
}
}
if ((cnt1 == 0 && cnt2 == 1) || (cnt1 == 1 && cnt2 == 0)) {
cout << "NO" << endl;
continue;
}
} else {
int cnt1 = 0, cnt2 = 0; // R, B
for (int i = 0; i < cnt[0]; i++) {
if (op[i] == 'R') {
cnt1 = 1;
} else {
cnt2 = 1;
}
}
if ((cnt1 == 0 && cnt2 == 1) || (cnt1 == 1 && cnt2 == 0)) {
cout << "NO" << endl;
continue;
}
int flag = 0;
for (int i = 0; i < num - 1; i++) {
cnt1 = 0, cnt2 = 0;
if (flag) break;
for (int j = cnt[i] + 1; j < cnt[i + 1]; j++) {
if (op[j] == 'R') {
cnt1 = 1;
} else {
cnt2 = 1;
}
}
if ((cnt1 == 0 && cnt2 == 1) || (cnt1 == 1 && cnt2 == 0)) {
cout << "NO" << endl;
flag = 1;
continue;
}
}
if (flag) continue;
cnt1 = 0, cnt2 = 0; // R, B
for (int i = cnt[num - 1]; i < len; i++) {
if (op[i] == 'R') {
cnt1 = 1;
} else {
cnt2 = 1;
}
}
if ((cnt1 == 0 && cnt2 == 1) || (cnt1 == 1 && cnt2 == 0)) {
cout << "NO" << endl;
continue;
}
}
}
cout << "YES" << endl;
}
return 0;
}
第二个正确的答案:
#include <bits/stdc++.h>
using namespace std;
inline void solve() {
int n;
string str;
cin >> n >> str;
str = "W" + str + "W";
++n;
vector<int> B(n + 5, 0), R(n + 5, 0);
for (int i = 1; i <= n; ++i) {
B[i] = B[i - 1];
R[i] = R[i - 1];
if (str[i] == 'B') ++B[i];
else if (str[i] == 'R') ++R[i];
}
int lst = 0;
for (int i = 1; i <= n; ++i) {
if (str[i] == 'W') {
if (i == lst + 1) {
lst = i;
continue;
}
if (R[i] - R[lst] == 0 || B[i] - B[lst] == 0) {
cout << "NO\n";
return;
}
lst = i;
}
}
cout << "YES\n";
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T;
cin >> T;
while (T--) {
solve();
}
return 0;
}
最近好忙。 唉。