Atcoder Beginner Contest 372(A-D)
A. delete
思路
模拟
直接输出即可
代码
void solve()
{
std::string s;
std::cin >> s;
for (int i = 0; i < s.size(); i++)
{
if (s[i] != '.')
{
std::cout << s[i];
}
}
}
B. 3^A
思路
二分
由于 \(0 \le A_i \le 10\) \((1 \le i \le N)\),可以不断二分
代码
int nums[11] = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049};
int ans[30];
int find(int x)
{
int l = -1, r = 11;
while(l + 1 < r)
{
int mid = (l + r) >> 1;
//std::cout << mid << endl;
if (nums[mid] <= x)
{
l = mid;
}
else
{
r = mid;
}
}
return l;
}
void solve()
{
int m = 0;
std::cin >> m;
//find(m);
int cnt = 0;
while(m)
{
int pos = find(m);
//std::cout << pos << endl;
m -= nums[pos];
ans[++cnt] = pos;
}
std::cout << cnt << endl;
for (int i = 1; i <= cnt; i++)
{
std::cout << ans[i] << ' ';
}
}
C. Count ABC Again
思路
模拟
先统计出\(ABC\)字符串的个数,然后计算每一次操作产生的影响
代码
void solve()
{
int n = 0, q = 0;
std::string s;
std::cin >> n >> q >> s;
int cnt = 0;
for (int i = 0; i < n - 2; i++)
{
if (s[i] == 'A' && s[i + 1] == 'B' && s[i + 2] == 'C')
{
cnt++;
i += 2;
}
}
//std::cout << cnt << endl;
int x = 0;
char ch = 0;
for (int i = 1; i <= q; i++)
{
std::cin >> x >> ch;
x--;
if (s[x] == 'A')
{
if (x < n - 2 && s[x + 1] == 'B' && s[x + 2] == 'C')
{
cnt--;
}
}
else if (s[x] == 'B')
{
if (x < n - 1 && x >= 1 && s[x - 1] == 'A' && s[x + 1] == 'C')
{
cnt--;
}
}
else if (s[x] == 'C')
{
if (x >= 2 && s[x - 1] == 'B' && s[x - 2] == 'A')
{
cnt--;
}
}
if (ch == 'A')
{
if (x < n - 2 && s[x + 1] == 'B' && s[x + 2] == 'C')
{
cnt++;
}
}
else if (ch == 'B')
{
if (x < n - 1 && x >= 1 && s[x - 1] == 'A' && s[x + 1] == 'C')
{
cnt++;
}
}
else if (ch == 'C')
{
if (x >= 2 && s[x - 1] == 'B' && s[x - 2] == 'A')
{
cnt++;
}
}
s[x] = ch;
std::cout << cnt << endl;
}
}
D. Buildings
题意概述
-
给定一个长度为\(n\)的排列,第\(i\)个数为\(a_i\)
-
对于\(a_i\), 如果数\(j\)满足
- \(i < j \leq N\)
- 在\(a_i\)和\(a_j\)之间没有大于\(a_j\)的
那么\(j\)就是合格的
-
对每个\(a_i\)求合格的\(j\)的个数
思路
-
对于一个合格的\(j\),\(a_j\)是\((a_i, a_j]\)中的最大值
-
对于\(a_i\),就是求它后面的最长上升子序列的长度
-
对于最前面的数还需要考虑后面的数,求起来很困难,我们可以从后面往前看
-
从后往前看,对于此时的数\(a_m\), 如果它前面的数比它大,那么\(a_m\)及其后面的数无法为它前面的数做贡献,扔掉就行,如果比它小的话,子序列长度就加1了
-
这不就是维护一个单调递减栈就好了吗?
-
答案就是此时栈的大小
代码
int nums[200010];
int ans[200010];
std::stack<int> stk;
void solve()
{
int n = 0;
std::cin >> n;
for (int i = 1; i <= n; i++)
{
std::cin >> nums[i];
}
stk.push(nums[n]);
for (int i = n - 1; i >= 1; i--)
{
ans[i] = stk.size();
while(!stk.empty() && stk.top() < nums[i])
{
stk.pop();
}
stk.push(nums[i]);
}
for (int i = 1; i <= n; i++)
{
std::cout << ans[i] << ' ';
}
}

浙公网安备 33010602011771号