Educational Codeforces Round 152 (Rated for Div. 2)
1.Atcoder Beginner Contest 312
2.Educational Codeforces Round 152 (Rated for Div. 2)
3.Codeforces Round 889 (Div. 2)4.Codeforces Round 888 (Div. 3)5.Codeforces Round 847 (Div. 3)6.Codeforces Round 890 (Div. 2)7.Codeforces Round 892 (Div. 2)8.Codeforces Round 893 (Div. 2)9.Educational Codeforces Round 15310.Codeforces Round 891 (Div. 3)11.Codeforces Round 894 (Div. 3)12.Educational Codeforces Round 154 (Rated for Div. 2)13.Codeforces Round 896 (Div. 2)14.Codeforces Round 855 (Div. 3)15.codeforces round 895 (div. 3)16.Codeforces Round 900 (Div. 3)17.Codeforces Round 901 (Div. 2)18.Codeforces Round 903 (Div. 3)C:
题意:
给你一个长度为n的01字符串s
,以及q
个询问每次询问给出一个区间[l, r]
,你需要将区间内的字符排序,问q
次询问之后可以得到多少个不同的01字符串?
思路:
直接暴力模拟时间复杂度为O(q(r - l)log(r - l))会超时,通过暴力做法可以发现时间主要卡在了排序上,那要怎么样才能简化排序呢?
假设区间[l, r]
为00010101111
,可以直观的发现真正有效的排序区间[l + 3, r - 4]
,因为头部和尾部已经是有序的了,这启发我们在每次询问的时候都要去找到有效的[l, r]
以此来简化排序,那要如何简化呢?
我们可以通过记录每个位置右边的一个1,和左边的第一个0来达到简化效果。
void solve()
{
int n, q; cin >> n >> q;
string s; cin >> s;
std::vector<int> last1(n, n); // 右边第一个1
std::vector<int> last0(n, -1); // 左边第一个0
for(int i = 0;i < n;i++) // 注意边界
{
if(i > 0)
{
last0[i] = last0[i - 1];
}
if(s[i] == '0')
{
last0[i] = i;
}
if(n - i - 1 < n - 1)
{
last1[n - i - 1] = last1[n - i];
}
if(s[n - i - 1] == '1')
{
last1[n - i - 1] = n - i - 1;
}
}
set<PII> ms;
while(q--)
{
int l,r;std::cin >> l >> r;
if(last1[l - 1] > last0[r - 1])
{
ms.emplace(-1, -1);
} else
{
ms.emplace(last1[l - 1], last0[r - 1]);
}
}
cout << ms.size() << endl;
}
D:
题意:
给你一个只有0, 1, 2
组成的数组,你可以进行两种操作:1. 选择一个数花一块钱把它变成红色。 2. 选择一个红色的数让它减一,顺便选左右两个数中的一个也变成红色。
问你最少花多少钱可以把数组全变成红色,初始数组全为蓝色
思路:
对于操作二我们知道,如果2
是红色的则可以免费把他的两边都变成红色,是1
的话可以让一边变成红色,所以直接贪心先把2
都变成红色,把2
变成红色之后,这个红色可以一直通过操作二传递到碰到0
为止
举个例子:001121100
,如果我们先把2
变成红色那么子区间0112110
都会因为操作二变成红的,代价为一枚金币.
void solve()
{
int n; cin >> n;
std::vector<int> a(n + 1);
std::vector<int> st(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (a[i] == 2 && !st[i])
{
ans ++;
int l = i;
while (a[l] != 0 && l > 0) st[l] = 1, l--;
st[l] = 1;
int r = i;
while (a[r] != 0 && r <= n) st[r] = 1, r++;
st[r] = 1;
}
}
for (int i = 1; i <= n; i++)
{
if (a[i] == 1 && !st[i])
{
ans++;
bool used = false;
if (!st[i - 1] && i > 1) st[i - 1] = 1, used = true;
int r = i;
while (a[r] != 0 && r <= n) st[r] = 1, r++;
if (!used) st[r] = 1;
}
}
for (int i = 1; i <= n; i++) if (!st[i]) ans++;
cout << ans << endl;
}
本文作者:自动机
本文链接:https://www.cnblogs.com/monituihuo/articles/17588075.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步