牛客刷题-Day26
今日刷题:\(F-J\)
G 小C的记事本

解题思路
模拟、栈:用栈来存储每次变化的字符串,栈顶即为最新的字符串状态。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
int q;
int main() {
ios::sync_with_stdio(false);
while (cin >> q) {
stack<string> stk;
string str;
int k;
int t;
while (q--) {
cin >> t;
if (t == 1) {
cin >> str;
if (stk.empty())
stk.push(str);
else
stk.push(stk.top() + str);
} else if (t == 2) {
cin >> k;
string tmp(stk.top().begin(), stk.top().end() - k);
stk.push(tmp);
} else if (t == 3) {
cin >> k;
cout << stk.top()[k - 1] << endl;
} else {
stk.pop();
}
}
}
return 0;
}
H Keep In Line

解题思路
模拟、队列:当 opt=in,则入队,标记该 name=1;否则出队,标记 name=0,若队首为 name,则是正常出队,否则将插队的出队。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int T, n;
void solve() {
map<string, int> st;
queue<string> que;
cin >> n;
int res = 0;
for (int i = 0; i < n; i++) {
string opt, name;
cin >> opt >> name;
if (opt == "in") {
st[name] = 1;
que.push(name);
} else {
st[name] = 0;
if (name == que.front())
res++;
while (!que.empty() && !st[que.front()])
que.pop();
}
}
cout << res << endl;
}
int main() {
cin >> T;
while (T--)
solve();
return 0;
}
J [NOIP2016]蚯蚓

解题思路
参考:P2827 NOIP2016 提高组 蚯蚓
首先最直接的想法 \(O(mlogm)\):每次取最长的蚯蚓 \(x\),新产生两只蚯蚓的长度为 \(\lfloor{px}\rfloor\) 和 \(x-\lfloor{px}\rfloor\),然后其余蚯蚓长度 \(+q\),则等价于新产生的蚯蚓长度 \(-q\)。
那么在 \([t,t+1)\) 时(\(t\in Z \bigcap t\in[0,n)\)),蚯蚓真实长度为 \(x+qt\),然后在此基础上新产生两只蚯蚓。即:
- 取最长的蚯蚓 \(x'\),真实长度为 \(x=x'+qt\);
- 划分:\(\lfloor{px}\rfloor\) 和 \(x-\lfloor{px}\rfloor\);
- 新产生蚯蚓:\(\lfloor{px}\rfloor-q-qt\),\(x-\lfloor{px}\rfloor-q-qt\)。
最终输出时全局偏移量为 \(mt\)。
优化:首先考虑 \(q=0\),即不会增长。每次取最长的蚯蚓 \(x\),新产生两只蚯蚓的长度为 \(\lfloor{px}\rfloor\) 和 \(x-\lfloor{px}\rfloor\)。假设 \(x_1\ge x_2\),则显然有 \(\lfloor{px_1}\rfloor\ge\lfloor{px_2}\rfloor\),那么是否 \(x_1-\lfloor{px_1}\rfloor\ge x_2-\lfloor{px_2}\rfloor\)?
证明:\(x_1-x_2\in Z\),\(x_1-x_2\ge p(x_1-x_2)\),\(x_1-x_2+px_2\ge px_1\),\(\lfloor x_1-x_2+px_2\rfloor\ge\lfloor px_1\rfloor\),\(\lfloor px_2\rfloor+x_1-x_2\ge\lfloor px_1\rfloor\),\(x_1-\lfloor{px_1}\rfloor\ge x_2-\lfloor{px_2}\rfloor\)。
考虑 \(q>0\)。假设某一秒,切开 \(x_1\),下一秒,切开 \(x_2+q\)。\(x_2+q\) 在上一秒时为 \(x_2\),因此 \(x_1≥x_2\)。证明目标是 \(⌊px_1⌋+q≥⌊p(x_2+q)⌋\) 和 \(x_1−⌊px_1⌋+q≥x_2+q−⌊p(x_2+q)⌋\)。
对于 \(⌊px_1⌋+q≥⌊p(x_2+q)⌋\):\(⌊px_1⌋+q=⌊px_1+q⌋\ge⌊px_2+q⌋\ge⌊px_2+pq⌋\ge⌊p(x_2+q)⌋\);
对于 \(x_1−⌊px_1⌋+q≥x_2+q−⌊p(x_2+q)⌋\):\(x_1−⌊px_1⌋+q≥x_2−⌊px_2⌋+q\ge x_2−⌊px_2+pq⌋+q\ge x_2−⌊p(x_2+q)⌋+q\);
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, MIN = -1e9;
typedef pair<int, int> PII;
int n, m, q, u, v, t;
int a[N];
queue<int> que[3];
int main() {
scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
for (int i = n; i; i--)
que[0].push(a[i]);
for (int i = 0; i < m; i++) {
PII p = max({make_pair(que[0].empty() ? MIN : que[0].front(), 0),
make_pair(que[1].empty() ? MIN : que[1].front(), 1),
make_pair(que[2].empty() ? MIN : que[2].front(), 2)});
int x = p.first + q * i, j = p.second;
que[j].pop();
int b = 1ll * x * u / v, c = x - b;
que[1].push(b - q - q * i);
que[2].push(c - q - q * i);
if (i % t == t - 1)
printf("%d ", x);
}
printf("\n");
for (int i = 1; i <= n + m; i++) {
PII p = max({make_pair(que[0].empty() ? MIN : que[0].front(), 0),
make_pair(que[1].empty() ? MIN : que[1].front(), 1),
make_pair(que[2].empty() ? MIN : que[2].front(), 2)});
int x = p.first, j = p.second;
que[j].pop();
if (i % t == 0)
printf("%d ", x + q * m);
}
printf("\n");
return 0;
}
本文来自博客园,作者:Cocoicobird,转载请注明原文链接:https://www.cnblogs.com/Cocoicobird/p/19449649
浙公网安备 33010602011771号