CWOI 2025.03.21 考试
T1 CF1427D Unshuffling a Deck
神秘构造题,赛场上的构造太劣了挂了 24pts。
首先,\(w\) 的范围明示需要 \(n\) 次操作以内排完,所以我们考虑每次让升序序列变长 \(1\),可以发现,如果我们的序列是 \([x + 1,\ldots,x,\ldots]\),那我们就可以把 \(x + 1\) 翻到 \(x\) 后面去,同时如果 \(x + 1\) 后面已经有序,那我们就可以一起翻过去,这样就可以在 $ O(n)$ 次操作内排完序。
T2 CF1473E Minimum Path
之前做过的原题,首先,原题中的限制相当于最短路加上最小边权,减去最大边权,根据贪心思想,我们又可以将限制弱化为加上一条边的边权,减去一条边的边权,因为加上的一定是最小的,减去的一定是最大的。
我们可以考虑分层图,第一层是没考虑 \(\min\) 和 \(\max\) 的,第二层是只考虑了 \(\max\) 的,第三层是只考虑了 \(\min\) 的,第四层是既考虑了 \(\min\) 又考虑了 \(\max\) 的,答案就是第四层的 \(dis\),跑一遍 Dijkstra 就好了。
T3 Luogu P5532 [CCO 2019] Sirtet
第一眼还以为是大模拟,就直接没写,赛后听 zcy 说 SPFA 被卡了,才知道这是个差分约束。
我们可以将问题转化为每一个点向下掉的最大距离。
先分类讨论一下,如果下面是 .,则可以向下掉,连边权为 \(1\) 的边,否则,就不能,连边权为 \(0\) 的边。联通块内相邻的点互相连边权为 \(0\) 的边,然后可以直接跑 01bfs(但是 01bfs 为什么跑不过带 \(\log\) 的 Dijkstra),统计答案即可。
T4 还没改。
这个得贴个代码,有点抽象。
#include <bits/extc++.h>
#define int long long
#define pii pair<int,int>
using namespace std;
constexpr int MAXN = 1e6 + 5,MV[4][2]{{1,0},{-1,0},{0,1},{0,-1}};
int n,m,dis[MAXN];
inline int getID(int x,int y)
{return (x - 1) * m + y;}
vector<vector<char> > ch,ans;
vector<pii> g[MAXN];
bool Vis[MAXN],vis[MAXN];
inline void dfs(int x,int y,int pre)
{
Vis[getID(x,y)] = 1;
if(pre)
g[getID(x,y)].emplace_back(pre,0),g[pre].emplace_back(getID(x,y),0);
for(int i = 0;i < 4;i++)
{
int dx = x + MV[i][0],dy = y + MV[i][1];
if(dx < 1 || dx > n || dy < 1 || dy > m || Vis[getID(dx,dy)] || ch[dx][dy] == '.')
continue;
dfs(dx,dy,getID(x,y));
}
}
inline void bfs()
{
deque<pii> q;
memset(dis,0x3f,sizeof(dis));
for(int i = 1;i <= m;i++)
q.emplace_back(getID(n,i),0);
while(!q.empty())
{
int u = q.front().first,d = q.front().second;
q.pop_front();
if(vis[u])
continue;
vis[u] = 1,dis[u] = d;
for(auto& [v,w] : g[u])
{
if(!w)
q.emplace_front(v,d);
else
q.emplace_back(v,d + 1);
}
}
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin >> n >> m;
ch.resize(n + 1),ans.resize(n + 1);
for(int i = 1;i <= n;i++)
{
ch[i].resize(m + 1),ans[i].resize(m + 1,'.');
for(int j = 1;j <= m;j++)
cin >> ch[i][j];
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if(!Vis[getID(i,j)] && ch[i][j] == '#')
dfs(i,j,0);
}
}
for(int i = 1;i < n;i++)
{
for(int j = 1;j <= m;j++)
{
if(ch[i + 1][j] == '.')
g[getID(i + 1,j)].emplace_back(getID(i,j),1);
else if(ch[i][j] == '.')
g[getID(i + 1,j)].emplace_back(getID(i,j),0);
}
}
bfs();
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if(ch[i][j] == '#')
ans[i + dis[getID(i,j)]][j] = '#';
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
cout << ans[i][j];
cout << "\n";
}
}

浙公网安备 33010602011771号