通过的题目:B、G、H、I、K
B-Brexit Negotiations(反向拓扑+贪心)
题意:给你n 个会议,依次给出每个会议的持续时间、开这个会议前要开的会议编号,在开每个会议前,要回顾当前会议前的所有会议,每个会议回顾 1 个单位时间,问最长会议的最短时间。
题解:看到诸如前继结点的东西想到拓扑排序,但是建边的时候需要反向建边,用优先队列贪心选择最小t[i]的点,否则如果正向贪心选择最大的t[i],其正确性得不到保障
诸如这种情况的话,正向贪心的时候会把第二个点放到最后,这样会造成贪心策略的错误,事实上反向建边就可避免这种错误。

#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl ' ' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=4e5+5; int tot,head[maxn]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } struct node{ int id,dep;ll t,ans; }p[maxn]; bool operator <(node a,node b){ return a.t>b.t; } int n,indeg[maxn],dep[maxn]; ll t[maxn],more,ans; void bfs(){ priority_queue<node> q; rep(i,1,n){ if(!indeg[i]){q.push(p[i]);} } while(!q.empty()){ int now=q.top().id;q.pop(); ans=max(ans,p[now].t+more); for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to; if(--indeg[v]==0) q.push(p[v]); } more--; } } int main(){ scanf("%d",&n);mem(head,-1); ans=0,more=n-1; rep(i,1,n){ p[i].id=i; scanf("%lld",&p[i].t); int k;scanf("%d",&k); rep(j,1,k){ int x;scanf("%d",&x); add(i,x);indeg[x]++; } } bfs(); printf("%lld ",ans); }
G-Game Design(思维+模拟)
题意:给你一个字符串(1<=其长度<=20),给你一些操作符"LRUD",表示往某一个方向走直到遇到障碍。现在给定终点(0,0)(0,0),要求构造一个起点以及若干障碍物,使得最后小球能够到达终点。注意必须是最后一步到达终点,中间到达终点即不合法。
第一个样例图如下:
题解:你可以假设从(0,0)开始跑,跑到最后的点作为终点,最后进行平移就好,但是要注意到诸如末尾结束为LRL,RLR,UDU,DUD,这种即为不合法(因为终点是个坑,掉进去就出不来的那种)。所以开局直接特判一下。同时要注意在字符串中间遇到诸如LRLRLR,UDUDUD这种不需要扩大范围。建图的时候一些障碍可能会重叠,但是最后只需要去重一下就行,毕竟没有要求障碍的数目也是最小。具体可以详细见代码。

#include <bits/stdc++.h> #define ll long long #define endl ' ' using namespace std; int r = 10; vector<pair<int, int> >a; map<char, int>mp; int main(){ ios::sync_with_stdio(false);cin.tie(0); string s; cin >> s; int px = 0, py = 0; mp['R'] = mp['L'] = 1; mp['U'] = mp['D'] = 2; if(s.length() >= 3 && s[s.length()-1] == s[s.length()-3] && mp[s[s.length()-1]] == mp[s[s.length()-2]]){ cout << "impossible" << ' '; return 0; } for(int i = 0; i < s.length(); i++){ if(i < s.length()-1 && (mp[s[i]] != mp[s[i-1]])) r += 5; if(s[i] == 'R') { px = r; a.push_back({px+1, py}); } else if(s[i] == 'L') {px = -r; a.push_back({px-1, py}); } else if(s[i] == 'U') {py = r; a.push_back({px, py+1}); } else if(s[i] == 'D') {py = -r; a.push_back({px, py-1}); } } for(int i = 0; i < a.size(); i++){ a[i].first -= px; a[i].second -= py; } a.pop_back(); sort(a.begin(), a.end()); a.erase(unique(a.begin(), a.end()), a.end()); cout << -px << " " << -py << ' '; cout << a.size() << ' '; for(int i = 0; i < a.size(); i++){ cout << a[i].first << " " << a[i].second << ' '; } }