Codeforces Round #604 (Div. 2) : http://codeforces.com/contest/1265
A. Beautiful String
链接
http://codeforces.com/contest/1265/problem/A
题意
给你一个字符串,字符串种只包含 ‘a’, ‘b’, ‘c’, ‘?’ 四种字符,要求使用 ‘a’, ‘b’, ‘c’ 替换字符串种的 ‘?’ 使得字符串是一个 Beautiful String(字符串中没有连续的两个字符是相同的)。
思路
- 遍历字符串,若当前字符 s[i] 是 ‘?’,先假设它是 ‘a’。
- 如果当前字符的前面有字符 s[i-1] 并且与当前字符相等(s[i-1] == s[i]),那么再假设它是 ‘b’。
- 如果后面有字符并且与当前字符相等,那么当前字符可能是 ‘b’ 也可能是 ‘c’,(因为不知道 1.1. 成不成立)需要在联合前面的字符判定,因为可能当前字符是 ‘b’ (1.1. 成立),所以假设当前字符是 ‘c’,再尝试判断与前面的字符是否相等,如果相等(说明 1.1. 不成立)改成 ‘b’,如果不相等,说明前后都不等,不用改了。
- 遍历的同时做合理性检查,如果当前字符不是第一个字符,检查当前字符是否与前一个字符相等,相等则返回 -1。
AC代码
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
int t;
cin>>t;
string s;
while(t--) {
cin>>s;
bool ans = 0;
int n = s.size();
for (int i = 0; i < n; ++i) {
if(s[i] == '?') {
s[i] = 'a';
if(i > 0 && s[i-1] == s[i]) s[i] = 'b';
if(i < n && s[i] == s[i+1]) s[i] = 'c';
if(i > 0 && s[i-1] == s[i]) s[i] = 'b';
}
if(i != 0 && s[i-1] == s[i]) {
ans = 1;
break;
}
}
if(ans) cout<<-1<<endl;
else cout<<s<<endl;
}
return 0;
}
B. Beautiful Numbers
链接
http://codeforces.com/contest/1265/problem/B
题意
给你一个排列,问你 1... n 1...n 1...n 中哪几个数是 Beautiful Numbers(在排列中截取一段 [ l , r ] [l, r] [l,r],使得这一段是一个排列,排列 1... m 1...m 1...m 的最大数字 m m m 就是 Beautiful Numbers)。
输出一个字符串,如果第 i i i 个数是 Beautiful Numbers,那么第 i i i 个字符是 ‘1’,否则是 ‘0’。
思路
双指针。
分析题目,可知 1 1 1 一定是 Beautiful Numbers。
一个排列必然是需要 1 1 1 的,那么先找到 1 1 1 的位置,两个指针都指向 1 1 1 的位置。
对于每个数字都尝试是否是 Beautiful Numbers。
具体地,从 1 1 1 的位置开始扩展,每次向左或向右扩展 1 1 1 位,向左还是向右扩展取决于左右两边数字的大小,直观上,先扩展小的数才有可能找到一个排列。记录每次所能得到的最大的连续数字,并当前数字相比较,如果相等,说明两个指针中间的这段就是一个排列,当前数字是 Beautiful Numbers。
PS:在我的实现中记录目前是否得到这个数字的 flag[] 数组需要初始化到 n+1,因为之后是通过判断 flag[i] 是否是 0 0 0 来判断连续的,如果受上次计算的影响 flag[n+1] 也是 1 1 1,那么最后一次的最大连续数字将会变成 n + 1 n+1 n+1 所以一定要使得 flag[n+1] = 0。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200100;
int t, n, a[MAXN], flag[MAXN];
int main(int argc, char const *argv[])
{
cin>>t;
while(t--) {
cin>>n;
int p, q;
for (int i = 1; i <= n; ++i) {
cin>>a[i];
if(a[i] == 1) p = q = i;
}
for (int i = 0; i <= n+1; ++i) flag[i] = 0;
flag[1] = 1;
string ans = "1";
int cnt = 1;
for (int i = 2; i <= n; ++i) {
if(p == 1) q++;
else if(q == n) p--;
else a[p-1] < a[q+1] ? p-- : q++;
flag[a[q]] = 1;
flag[a[p]] = 1;
while(flag[cnt]) cnt++;
cnt--;
if(cnt == i) ans += "1";
else ans += "0";
}
cout<<ans<<endl;
}
return 0;
}