ACM练习坑(待填)
这几天刚到学校,空闲时间比较多,又加入了ACM队,打算重整信心捡起以前的知识,现在就来阅题填坑啦
以下题目来自codeforces
我已经做了:
15/50
Codeforces Round #433 (Div. 1, based on Olympiad of Metropolises)
A.Planning
有n(<=300000)个飞机,第i个飞机原计划在i时刻起飞。现在机场延误,需要让这n个飞机在[ k , k+n ]时刻全部飞完,每个时刻只能飞一个飞机,同时每个飞机不能比原计划更早起飞,也就是飞机i的起飞区间应该是[ i , n+k ]。每个飞机有一个延误系数,这个飞机的延误代价=延误系数*延误时间(如果按照原计划时间起飞则延误代价=0)。求最小延误代价,以及每个飞机的起飞时刻。
贪心很容易想到,但是有时间的限制,算作二维问题
就让当前状态满足一维的限制,另一维取最优即可
即当前加入的都是可选状态。
#include <bits/stdc++.h>
#define maxn 300010
using namespace std;
struct Node {
int c, id;
} p[maxn];
bool operator < (const Node& a, const Node& b) {
return a.c < b.c;
}
priority_queue<Node> q;
int n, k;
int main() {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++ i)
scanf("%d", &p[i].c), p[i].id = i;
for(int i = 1; i <= k; ++ i)
q.push(p[i]);
long long ans = 0;
for(int i = k+1; i <= k+n; ++ i) {
if(i <= n) q.push(p[i]);
Node now = q.top(); q.pop();
p[now.id].id = i;
ans += (long long)(i-now.id)*now.c;
}
printf("%I64d\n", ans);
for(int i = 1; i <= n; ++ i)
printf("%d ", p[i].id);
return 0;
}
B.Jury Meeting
现在有(n+1)个城市,其中第1~n个城市每个城市有一个人,第0个城市是人们需要聚集的地方。还有m条航班,每条航班从0到其他城市或从其他城市到0,当天即可抵达,现在需要选定一个时间段,长度为k天,使得这一个时间段里人们都在0城市工作(航班抵达和离开0城市的那一天不能进行工作),问把n个人送到0城市,工作完成后再送回去的最小花费。
贪心+预处理
#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;
int n, m, k;
struct Node {
int d, f, t, c;
} p[maxn];
bool operator < (const Node& a, const Node& b) {
return a.d < b.d;
}
long long ans1[maxn];
long long ans2[maxn];
int vis[maxn];
int cnt;
int main() {
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= m; ++ i)
scanf("%d%d%d%d", &p[i].d, &p[i].f, &p[i].t, &p[i].c);
sort(p+1, p+1+m);
memset(ans1, -1, sizeof ans1);
memset(ans2, -1, sizeof ans2);
memset(vis, 0, sizeof vis);
cnt = 0;
long long sum = 0;
for(int i = 1; i <= m; ++ i) {
if(p[i].f) {
if(vis[p[i].f]) {
if(p[i].c < vis[p[i].f])
sum = sum-vis[p[i].f]+p[i].c, vis[p[i].f] = p[i].c;
}
else {
vis[p[i].f] = p[i].c;
sum += p[i].c;
cnt ++;
}
}
if(cnt == n)
ans1[p[i].d] = sum;
}
memset(vis, 0, sizeof vis);
cnt = 0;
sum = 0;
for(int i = m; i; -- i) {
if(p[i].t) {
if(vis[p[i].t]) {
if(p[i].c < vis[p[i].t])
sum = sum-vis[p[i].t]+p[i].c, vis[p[i].t] = p[i].c;
}
else {
vis[p[i].t] = p[i].c;
sum += p[i].c;
cnt ++;
}
}
if(cnt == n)
ans2[p[i].d] = sum;
}
int mx = 0;
for(int i = 1; i <= m; ++ i)
mx = max(mx, p[i].d);
for(int i = 1; i <= mx; ++ i)
if(ans1[i-1] != -1) {
if(ans1[i] == -1) ans1[i] = ans1[i-1];
else ans1[i] = min(ans1[i], ans1[i-1]);
}
for(int i = mx; i; -- i)
if(ans2[i+1] != -1) {
if(ans2[i] == -1) ans2[i] = ans2[i+1];
else ans2[i] = min(ans2[i], ans2[i+1]);
}
long long ret = -1;
for(int i = 1; i <= mx-k; ++ i) {
if(ans1[i] > 0 && ans2[i+k+1] > 0) {
if(ret == -1) ret = ans1[i]+ans2[i+k+1];
else ret = min(ret, ans1[i]+ans2[i+k+1]);
}
}
printf("%I64d\n", ret);
return 0;
}
C.Boredom
主席树,二维前缀和
这样就可以快速的查询某个子矩阵里标记点的个数,对于每个查询的矩阵,我们只需要求不在这个矩阵里的所有 beautiful rectangles个数即可,也就是两个被标记的点都在查询矩阵的上方,下方,左方,右方,最后在去一下重。
#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
typedef long long ll;
int n, q;
int lc[maxn*30], rc[maxn*30], size[maxn*30];
int cnt = 0, t[maxn], p[maxn];
int update(int root, int l, int r, int x, int k) {
int now = ++ cnt;
size[now] = size[root] + k;
if(l == r) return now;
int mid = l + r >> 1;
if(x <= mid) {
lc[now] = update(lc[root], l, mid, x, k);
rc[now] = rc[root];
}
else {
lc[now] = lc[root];
rc[now] = update(rc[root], mid+1, r, x, k);
}
return now;
}
int query(int root, int l, int r, int L, int R) {
if(root == 0 || L > R || L < 1 || R > n) return 0;
if(L == l && R == r)
return size[root];
int mid = l + r >> 1;
if(R <= mid) return query(lc[root], l, mid, L, R);
if(L > mid) return query(rc[root], mid+1, r, L, R);
return query(lc[root], l, mid, L, mid)+query(rc[root], mid+1, r, mid+1, R);
}
ll f(int x) { return (ll)x*(x-1)/2; }
int main() {
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; ++ i) {
scanf("%d", &p[i]);
t[i] = update(t[i-1], 1, n, p[i], 1);
}
ll ans = 0;
int l, d, r, u;
while(q --) {
scanf("%d%d%d%d", &l, &d, &r, &u);
int t1 = query(t[l-1], 1, n, 1, n);
int t2 = query(t[n], 1, n, 1, d-1);
int t3 = query(t[n], 1, n, 1, n) - query(t[r], 1, n, 1, n);
int t4 = query(t[n], 1, n, u+1, n);
int t5 = query(t[l-1], 1, n, 1, d-1);
int t6 = t2-query(t[r], 1, n, 1, d-1);
int t7 = query(t[l-1], 1, n, u+1, n);
int t8 = query(t[n], 1, n, u+1, n)-query(t[r], 1, n, u+1, n);
ans = f(n)-(f(t1)+f(t2)+f(t3)+f(t4)-f(t5)-f(t6)-f(t7)-f(t8));
printf("%I64d\n", ans);
}
return 0;
}
Codeforces Round #432 (Div. 1, based on IndiaHacks Final Round 2017)
A.需要一些数学脑洞??范围1000??
It's easier to visualize this in 2D first. Fix a point p. If all other points form angles that are 90 degrees or greater, they must all be in different quadrants, so there can be at most 4 such points. In k dimension, this generalizes to 2*k such points, so for five dimensions, there can only be at most 10 other points. Thus, we can run the naive solution for small n and print 0 otherwise.
#include <bits/stdc++.h>
#define maxn 105
using namespace std;
struct Point {
int x[5];
void read() {
for(int i = 0; i < 5; ++ i)
scanf("%d", &x[i]);
}
}p[maxn];
long long operator * (const Point& a, const Point& b) {
long long ret = 0;
for(int i = 0; i < 5; ++ i)
ret += (long long)a.x[i]*b.x[i];
return ret;
}
Point operator - (const Point& a, const Point& b) {
Point ret;
for(int i = 0; i < 5; ++ i)
ret.x[i] = a.x[i] - b.x[i];
return ret;
}
int n;
bool fg;
vector<int> G;
bool pd(int x, int y, int z) {
return (p[y]-p[x]) * (p[z]-p[x]) > 0;
}
int main() {
scanf("%d", &n);
if(n > 100) {
printf("0\n");
return 0;
}
for(int i = 1; i <= n; ++ i)
p[i].read();
for(int i = 1; i <= n; ++ i) {
fg = true;
for(int j = 1; j <= n; ++ j) {
for(int k = j+1; k <= n; ++ k)
if(i != j && i != k) {
if(pd(i, j, k)) {
fg = false;
break;
}
}
if(!fg) break;
}
if(fg) G.push_back(i);
}
printf("%d\n", G.size());
for(int i = 0; i < G.size(); ++ i)
printf("%d\n", G[i]);
return 0;
}
B.Arpa and a list of numbers
枚举因子然后就好做了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2000010;
const ll inf = 1e18;
ll s[maxn];
int a[maxn];
bool used[maxn];
int n;
ll x, y;
int main(){
scanf("%d%I64d%I64d", &n, &x, &y);
int p = x / y;
for(int i = 1; i <= n; ++ i) {
int t;
scanf("%d", &t);
a[t] ++;
s[t] += t;
}
ll ans = inf;
for(int i = 1; i < maxn; ++ i)
a[i] += a[i-1], s[i] += s[i-1];
for(int i = 2; i <= 1000000; ++ i) {
if(used[i]) continue;
ll tmp = 0;
for(int j = i; j <= 1000000+i; j += i) {
used[j] = true;
int k = max(j-i+1, j-p);
tmp += ((ll)(a[j]-a[k-1])*j - (s[j]-s[k-1]))*y + (ll)(a[k-1]-a[j-i])*x;
}
ans = min(ans, tmp);
}
printf("%I64d", ans);
return 0;
}
我能说我的A题没看懂嘛。。
B.Minimum and Maximum
This is an interactive problem. You have to use flush operation right after printing each line. For example, in C++ you should use function fflush(stdout)
交互式询问一个数列的最大最小值
两个分成一组查询
#include<bits/stdc++.h>
using namespace std;
char ask(int x, int y) {
printf("? %d %d\n", x, y);
fflush(stdout);
char c;
cin >> c;
return c;
}
void solve() {
int n;
cin >> n;
if(n == 1) {
printf("! 1 1\n");
return;
}
char c = ask(1, 2);
int mx, mn;
if(c == '=') mx = mn = 1;
if(c == '<') mx = 2, mn = 1;
if(c == '>') mx = 1, mn = 2;
for(int i = 3; i <= n; i += 2) {
if(i == n) {
if(ask(mx, i) == '<') mx = i;
if(ask(mn, i) == '>') mn = i;
}
else {
c = ask(i, i+1);
if(c == '>') {
if(ask(mx, i) == '<') mx = i;
if(ask(mn, i+1) == '>') mn = i+1;
}
else {
if(ask(mn, i) == '>') mn = i;
if(ask(mx, i+1) == '<') mx = i+1;
}
}
}
printf("! %d %d\n", mn, mx);
fflush(stdout);
}
int main() {
int Test;
scanf("%d",&Test);
while (Test--)
solve();
return 0;
}
C.Bulmart
竟然养成了过了样例就交的坏习惯
小错误不断啊。。
错因是没有开longlong,两数相乘的范围没有看到,最后还写T了。。感觉很绝望
然后把bfs的常数省了省,好像还是不行。
唔。把二分里套的sort省掉以后就A了。。
#include <bits/stdc++.h>
#define maxn 5010
using namespace std;
int n, m;
struct Edge {
int to, nxt;
}edge[maxn*maxn*2];
int h[maxn], cnt;
void addedge(int u, int v) {
++ cnt;
edge[cnt].to = v;
edge[cnt].nxt = h[u];
h[u] = cnt;
}
struct qwq { int num, price, dis; } test;
bool operator < (const qwq& a, const qwq& b) {
return a.price < b.price;
}
vector<pair<int, int> > Gpa[maxn];
vector<qwq> ans;
int G, R, A;
int tim, vis[maxn], que[maxn], dis[maxn];
void bfs() {
ans.clear();
int head = 0, tail = 0;
que[tail ++] = G;
vis[G] = ++ tim;
dis[G] = 0;
while(head != tail) {
int u = que[head ++];
for(int i = 0; i < Gpa[u].size(); ++ i) {
test.dis = dis[u];
test.num = Gpa[u][i].second;
test.price = Gpa[u][i].first;
ans.push_back(test);
}
for(int i = h[u]; i; i = edge[i].nxt) {
int v = edge[i].to;
if(vis[v] != tim) {
vis[v] = tim;
dis[v] = dis[u]+1;
que[tail ++] = v;
}
}
}
sort(ans.begin(), ans.end());
}
bool judge(int x) {
long long nw = 0;
int r = R;
for(int i = 0; i < ans.size(); ++ i) {
qwq& test = ans[i];
if(test.dis > x) continue;
if(r > test.num) {
r -= test.num;
nw += (long long)test.num*test.price;
if(nw > A) return false;
}
else {
nw += (long long)r*test.price;
if(nw > A) return false;
else return true;
}
}
return false;
}
void solve() {
bfs();
int l = 0, r = n;
while(l < r) {
int mid = l + (r-l)/2;
if(judge(mid)) r = mid;
else l = mid+1;
}
if(l != n)printf("%d\n", l);
else printf("-1\n");
}
int main() {
scanf("%d%d", &n, &m);
int u, v, d, q;
for(int i = 1; i <= m; ++ i) {
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
scanf("%d", &m);
for(int i = 1; i <= m; ++ i) {
scanf("%d%d%d", &u, &v, &d);
Gpa[u].push_back(make_pair(d, v));
}
scanf("%d", &q);
while(q --) {
scanf("%d%d%d", &G, &R, &A);
solve();
}
return 0;
}
D.Running Over the bridges
感觉像守望者的逃离。。贪心尽量放在后面
#include <bits/stdc++.h>
#define maxn 200010
using namespace std;
vector<long long> ans;
int n;
long long r, l[maxn], t[maxn];
int main() {
scanf("%d%I64d", &n, &r);
for(int i = 1; i <= n; ++ i)
scanf("%I64d", &l[i]);
for(int i = 1; i <= n; ++ i)
scanf("%I64d", &t[i]);
long long re = 0, nw = 0, tot = 0;
for(int i = 1; i <= n; ++ i) {
if(t[i] < l[i]) {
printf("-1\n");
return 0;
}
if(re >= l[i]) {
re -= l[i];
nw += l[i];
continue;
}
l[i] -= re;
t[i] -= re;
nw += re;
re = 0;
if(l[i]*2 <= t[i])
nw += l[i]*2;
else {
long long T = t[i] - l[i];
l[i] -= T;
t[i] -= T*2;
nw += T*2;
for(long long j = nw; j < nw+t[i] && ans.size() < 100010; j += r)
ans.push_back(j);
nw += l[i];
tot += l[i] / r;
re = l[i] % r;
if(re) {
tot ++;
re = r - re;
}
}
}
if(ans.size() == 0) printf("0\n");
else {
printf("%I64d\n", tot);
if(ans.size() <= 100000) {
sort(ans.begin(), ans.end());
for(int i = 0; i < ans.size(); ++ i)
printf("%I64d ", ans[i]);
}
}
return 0;
}
E.关于排行榜的滚动,先按照成绩排一个名,d值为正的从得分score小到大搞一下,d值为负的score从大倒小搞一下
#include <bits/stdc++.h>
#define maxn 110
using namespace std;
int n;
bool vis[maxn];
struct People {
int val, d, id;
}p[maxn];
bool operator < (const People& a, const People& b) {
if(a.val != b.val) return a.val > b.val;
return a.id < b.id;
}
//优先级顺序
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++ i) {
scanf("%d%d", &p[i].val, &p[i].d);
p[i].id = i;
}
sort(p+1, p+1+n);
int ans = 0;
for(int i = n; i >= 1; -- i) {
if(vis[p[i].id]) continue;
if(p[i].d < 0) continue;
vis[p[i].id] = 1;
p[i].val += p[i].d;
for(int j = i-1; j; -- j) {
if(p[j+1] < p[j]) {
ans ++;
swap(p[j], p[j+1]);
} else break;
}
++ i;
}
for(int i = 1; i <= n; ++ i) {
if(vis[p[i].id]) continue;
vis[p[i].id] = 1;
p[i].val += p[i].d;
for(int j = i+1; j <= n; ++ j) {
if(p[j] < p[j-1]) {
ans ++;
swap(p[j-1], p[j]);
} else break;
}
-- i;
}
printf("%d\n", ans);
return 0;
}
G.Car Repair Shop
模拟区间查询
#include <bits/stdc++.h>
#define maxn 210
using namespace std;
int n, s[maxn], d[maxn];
int judge(int idx, int l, int r) {
for(int i = 1; i < idx; ++ i)
if(max(s[i], l) <= min(s[i]+d[i]-1, r))
return i;
return 0;
}
int main() {
scanf("%d", &n);
d[0] = 1;
for(int i = 1; i <= n; ++ i) {
scanf("%d%d", &s[i], &d[i]);
int idx = judge(i, s[i], s[i]+d[i]-1);
if(!idx) continue;
s[i] = 1;
idx = judge(i, s[i], s[i]+d[i]-1);
while(idx) {
s[i] = s[idx] + d[idx];
idx = judge(i, s[i], s[i]+d[i]-1);
}
}
for(int i = 1; i <= n; ++ i)
printf("%d %d\n", s[i], s[i]+d[i]-1);
return 0;
}
H.Delete Them
读懂题意是关键
#include <bits/stdc++.h>
using namespace std;
char s[110][110];
int n, m, x;
vector<int> G;
bool vis[110];
char ans[110];
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i)
scanf("%s", s[i]+1);
int len = -1;
for(int i = 1; i <= m; ++ i) {
scanf("%d", &x);
G.push_back(x);
vis[x] = true;
if(len == -1) len = strlen(s[x]+1);
else if(strlen(s[x]+1) != len) {
printf("No\n");
return 0;
}
}
for(int i = 1; i <= len; ++ i) {
char c = s[G[0]][i];
int fg = 0;
for(int j = 1; j < G.size(); ++ j)
if(s[G[j]][i] != c) {
ans[i] = '?';
fg = -1;
break;
}
if(!fg) ans[i] = c;
}
for(int i = 1; i <= n; ++ i) {
if(!vis[i] && strlen(s[i]+1) == len) {
int fg = 0;
for(int j = 1; j <= len; ++ j) {
if(ans[j] == '?') continue;
if(ans[j] != s[i][j]) {
fg = -1;
break;
}
}
if(!fg) {
printf("No");
return 0;
}
}
}
printf("Yes\n");
for(int i = 1; i <= len; ++ i)
putchar(ans[i]);
return 0;
}
I.Olympiad in Programming and Sports
费用流
#include <bits/stdc++.h>
#define maxn 3005
using namespace std;
int n, p, s;
int a[maxn], b[maxn];
struct Edge {
int to, nxt, w, dis;
}edge[200010];
int h[maxn], cnt = 1, S, T;
void addedge(int u, int v, int w, int dis) {
++ cnt;
edge[cnt].to = v;
edge[cnt].nxt = h[u];
edge[cnt].w = w;
edge[cnt].dis = dis;
h[u] = cnt;
swap(u, v), dis = -dis, w = 0;
++ cnt;
edge[cnt].to = v;
edge[cnt].nxt = h[u];
edge[cnt].w = w;
edge[cnt].dis = dis;
h[u] = cnt;
}
const int inf = 0x7fffffff/2;
queue<int> Q;
int dis[maxn], pre[maxn], ans;
bool vis[maxn];
bool spfa() {
for(int i = S; i <= T; ++ i)
dis[i] = -inf;
dis[S] = 0;
Q.push(S);
while(!Q.empty()) {
int u = Q.front(); Q.pop(); vis[u] = false;
for(int i = h[u]; i; i = edge[i].nxt) {
if(edge[i].w) {
int v = edge[i].to;
if(dis[v] < dis[u] + edge[i].dis) {
dis[v] = dis[u] + edge[i].dis;
pre[v] = i;
if(!vis[v]) vis[v] = true, Q.push(v);
}
}
}
} return dis[T] > 0;
}
void solve() {
int x = inf;
for(int i = pre[T]; i; i = pre[edge[i^1].to])
x = min(x, edge[i].w);
for(int i = pre[T]; i; i = pre[edge[i^1].to])
edge[i].w -= x, edge[i^1].w += x;
ans += x*dis[T];
}
void Maxcostflow() {
while(spfa())
solve();
}
int main() {
scanf("%d%d%d", &n, &p, &s);
for(int i = 1; i <= n; ++ i)
scanf("%d", &a[i]);
for(int i = 1; i <= n; ++ i)
scanf("%d", &b[i]);
S = 0, T = n+3;
int A = n+1, B = n+2;
for(int i = 1; i <= n; ++ i) {
addedge(S, i, 1, 0);
addedge(i, A, 1, a[i]);
addedge(i, B, 1, b[i]);
}
addedge(A, T, p, 0);
addedge(B, T, s, 0);
Maxcostflow();
printf("%d\n", ans);
vector<int> G;
G.clear();
for(int i = h[A]; i; i = edge[i].nxt)
if(edge[i].w == 1) G.push_back(edge[i].to);
sort(G.begin(), G.end());
for(int i = 0; i < G.size(); ++ i)
printf("%d ", G[i]);
printf("\n");
G.clear();
for(int i = h[B]; i; i = edge[i].nxt)
if(edge[i].w == 1) G.push_back(edge[i].to);
sort(G.begin(), G.end());
for(int i = 0; i < G.size(); ++ i)
printf("%d ", G[i]);
return 0;
}
J.Bottles
现在有n个瓶子,每个瓶子容量bi,已经装了ai的水
把所有的水转移到尽量少的瓶子至少需要几个瓶子?
满足上一问的情况下,最少转移多少单位的水?
dp[i][j][k]表示前i个瓶子选了j个瓶子已经装了k体积的水的最大不动的水的体积
#include <bits/stdc++.h>
using namespace std;
int n, need, sum, ans;
int f[110][10010], a[110], b[110];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++ i) {
scanf("%d", &a[i]);
need += a[i];
}
for(int i = 1; i <= n; ++ i) {
scanf("%d", &b[i]);
sum += b[i];
}
memset(f, -1, sizeof f);
f[0][0] = 0;
for(int i = 1; i <= n; ++ i)
for(int j = n; j >= 1; -- j)
for(int k = sum; k >= b[i]; -- k)
if(f[j-1][k-b[i]] != -1)
f[j][k] = max(f[j][k], f[j-1][k-b[i]]+a[i]);
ans = -1;
for(int i = 1; i <= n; ++ i) {
for(int j = need; j <= sum; ++ j)
ans = max(ans, f[i][j]);
if(ans != -1) {
printf("%d %d\n", i, need-ans);
break;
}
}
return 0;
}
2008-2009 ACM-ICPC, NEERC, Southern Subregional Contest
以下太难而且没有题解导致此比赛被弃坑回来再填吧
A题通过人数为0
点开比赛pdf并没有发现第一题是A题(纯属脑抽)
写了半天还以为题目很简单,看了样例发现自己题看错了(已扇自己一万次脸
那我就按照通过人数的顺序来了。。
G.Friends of Friends
最简单的一题,可惜还wa了,原因是没有sort(眼瞎看不懂英文increasing number)
#include <bits/stdc++.h>
#define maxn 51
using namespace std;
bool G[maxn][maxn], vis[maxn];
int n, x, y, num;
int cnt, ans[maxn];
int main() {
scanf("%d%d", &n, &x);
for(int i = 1; i <= n; ++ i) {
scanf("%d", &num);
for(int j = 1; j <= num; ++ j) {
scanf("%d", &y);
if(i != y) G[i][y] = G[y][i] = 1;
}
}
for(int i = 1; i <= n; ++ i) {
if(G[x][i])
for(int j = 1; j <= n; ++ j)
if(j != x && G[i][j] && !G[x][j] && !vis[j])
ans[++ cnt] = j, vis[j] = true;
}
if(cnt == 0) printf("0\n");
else {
printf("%d\n", cnt);
sort(ans+1, ans+1+cnt);
for(int i = 1; i <= cnt; ++ i)
printf("%d\n", ans[i]);
}
return 0;
}
F.Text Editor
脑子年久失修,10^6想成了10^5
简单的链表,怪不得过得人这么多(放在考场上要罚多少时啊喂)
#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;
char s[maxn], c[maxn];
int nxt[maxn], pre[maxn], cnt;
int main() {
scanf("%s", s+1);
int len = strlen(s+1);
int nw = 1;
cnt = 1;
for(int i = 1; i <= len; ++ i) {
if(s[i] == 'L' && nw != 1) nw = pre[nw];
else if(s[i] == 'R' && nxt[nw]) nw = nxt[nw];
else if(s[i] >= 'a' && s[i] <= 'z'){
++ cnt;
c[cnt] = s[i];
if(nxt[nw]) {
pre[nxt[nw]] = cnt;
nxt[cnt] = nxt[nw];
}
nxt[nw] = cnt;
pre[cnt] = nw;
nw = cnt;
}
}
nw = 1;
while(true) {
nw = nxt[nw];
if(nw)putchar(c[nw]);
else break;
}
return 0;
}
未完待续。。

浙公网安备 33010602011771号