2021-2022 ACM-ICPC Brazil Subregional Programming Contest
E. Escalator
分析:
-
这题没什么,就是一个队列的模拟
然后,一直被绕来绕去,不知道如何去维护当前的时间,与每个人到达时间的关系
不清楚,在何时,电梯实现状态的转换,从上升到下降 OR 下降到上升
-
电梯上升和下降两种状态,分两类
-
状态的转换:
仔细想假设现在电梯在上升,要实现状态的转换,分两种情况:
- 上升队列当中已经没人了
- 下一个要上升的人的到达时间,超过了电梯停止的时间
#include <bits/stdc++.h>
using namespace std;
priority_queue <int, vector<int>, greater<int> > q,p;
// 没必要用优先队列,题目已经保证了从小到大
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int t,fg;
cin>>t>>fg;
if(fg) q.push(t);
else p.push(t);
}
int t=0,ans=0;
while(!q.empty() && !p.empty())
{
int up=q.top(),down=p.top();
// 就分两类情况讨论
if(up<down)
{
ans+=10;
while(!q.empty() && q.top()<ans)
{
// q.top()>ans 即下一个人的到达时间超过的停止的时间
if(q.top()+10>ans) ans=q.top()+10;
q.pop();
}
}
else
{
ans+=10;
while(!p.empty() && p.top()<ans)
{
if(p.top()+10>ans) ans=p.top()+10;
p.pop();
}
}
}
// 经上述处理之后,必然有一个队列不为空
ans+=10;
int r=0;
while(!q.empty()) r=q.top()+10,q.pop();
while(!p.empty()) r=p.top()+10,p.pop();
cout<<max(ans,r)<<endl;
}
G. Getting in Shape
分析:
- 可以发现一串a加一个B的方案数就是斐波那契数列
- 用一个b还是多个b隔开,效果一样,又因为题目要保证字典序最小,所以一个b就行了
- 然后就是多个”一串a加一个b“的组合了,方案数为累乘
- 预处理斐波那契数列,再跑一边 D F S DFS DFS 即可,
#include <bits/stdc++.h>
#define int long long
using namespace std;
int f[105];
void init()
{
f[0]=f[1]=1;
for(int i=2;i<=72;i++) f[i]=f[i-1]+f[i-2];
}
int ans[105];
int fg;
void dfs(int u,int tot,int l)
{
if(u==1)
{
fg=1;
for(int i=1;i<tot;i++)
{
for(int j=1;j<=ans[i];j++) cout<<'A';
cout<<'B';
}
return ;
}
for(int i=l;i>=2;i--)
{
// 注意:当前要找的因子,必定小于等于之前的因子,故i从l开始遍历
// 不然就会超时,一直在反复遍历
if(!fg && u%f[i]==0)
{
ans[tot]=i-1;
dfs(u/f[i],tot+1,l=i);
}
}
}
signed main()
{
int n;
cin>>n;
if(n==1) { cout<<"A"<<endl; return 0; }
init();
dfs(n,1,72);
if(!fg) cout<<"IMPOSSIBLE"<<endl;
}
M. Monarchy in Vertigo
分析:
-
首先,要读懂题,发现要找的就是 D F S DFS DFS 序
多了一些操作:过程当中去掉某些节点,让求的便是过程当中的 D F S DFS DFS 序的首节点
-
用队列 + + + v i s vis vis 标记维护即可
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
vector <int> g[N];
int b[N];
queue <int> q;
void dfs(int u)
{
for(int v : g[u])
{
q.push(v);
dfs(v);
}
}
int vis[N];
signed main()
{
int n;
scanf("%d",&n);
int tot=1,cnt=0;
for(int i=1;i<=n;i++)
{
int t,x;
scanf("%d%d",&t,&x);
if(t==1) g[x].push_back(++tot);
else b[++cnt]=x;
}
q.push(1);
dfs(1);
int now=1;
for(int i=1;i<=cnt;i++)
{
vis[b[i]]=1;
if(vis[now])
{
int u=q.front();
while(!q.empty() && vis[u])
{
q.pop();
u=q.front();
}
now=u;
}
printf("%d\n",now);
}
}