题解 | ACGO巅峰赛#28
2025-12-08 20:05:24
发布于:江苏
ACGO巅峰赛#28
本题解包含三道竞赛题:
| 题目编号 | 题目标题 | 难度 |
|---|---|---|
| T1 | Alice的石子合并 | 普及/提高- |
| T3 | Alice的神秘二叉树 | 普及/提高- |
| T4 | Alice的棋盘游戏 | 普及/提高- |
T1 Alice的石子合并
题目大意
求出合并 堆石子的最小代价。
解题思路
对于每一堆石子,不管往右还是往左合并,都不会影响其他堆石子的属性 ,如果往左合并,则代价为 ,如果往右合并,则代价为 ,所以每堆石子的最小代价为 。但第一堆石子和最后一堆石子只能往一个方向合并,所以第一堆的最小代价为 ,最后一堆的最小代价为 。一共 堆石子,合并最小代价前 堆石子,即去掉最小代价最大的一堆石子,其他 堆石子的最小代价和即为最小总代价。
参考代码
#include<iostream>
#define ll long long
using namespace std;
const ll N=200005;
ll n,a[N],b[N],ans,tmp,mx;
int main(){
cin>>n;
for(ll i=1;i<=n;++i)cin>>a[i];
for(ll i=1;i<=n;++i)cin>>b[i];
for(ll i=1;i<=n;++i){
if(i==1)tmp=b[i];
else if(i==n)tmp=a[i];
else tmp=min(a[i],b[i]);
ans+=tmp;
mx=max(mx,tmp);
}
cout<<ans-mx;
return 0;
}
T3 Alice的神秘二叉树
题目大意
给出一棵二叉树的中序遍历和层序遍历,求出先序遍历。
解题思路
假设 为根节点,则先序遍历的结果为 的先序遍历 的先序遍历。
针对 ,假设 为根节点,先序遍历的结果为 的先序遍历 的先序遍历。
针对 ,假设 为根节点,先序遍历的结果为 的先序遍历 的先序遍历。
所以,只要知道某个区间 的根节点,就可以递归求出这个区间的先序遍历。
因为层序遍历的顺序为从根到叶、自左到右,所以区间 的根节点就是在 序列中出现最早的键。
记录每个键在 序列中的下标,每次查询的时间复杂度为 。
参考代码
#include<iostream>
#include<map>
#define ll long long
using namespace std;
const ll N=200005;
ll n,in[N],level[N],mn;
map<ll,ll> idx;
void work(ll l,ll r){
if(l>r)return;
mn=N;
ll w;
for(ll i=l;i<=r;++i){
if(idx[in[i]]<mn){
mn=idx[in[i]];
w=i;
}
}
cout<<in[w]<<' ';
work(l,w-1);
work(w+1,r);
return;
}
int main(){
cin>>n;
for(ll i=1;i<=n;++i)cin>>in[i];
for(ll i=1;i<=n;++i){
cin>>level[i];
idx[level[i]]=i;
}
work(1,n);
return 0;
}
T4 Alice的棋盘游戏
题目大意
判断先手是否必胜,并输出首回合必胜的走法。
解题思路
为了方便讲解,假设 指在 位置,以前走过 步时,先手是否能赢。 表示能, 表示不能。
求 :
- 如果 ,即下一步是先手走,那么只要 其中一个为 ,就可以判定 ,因为先手走到这一步时可以选择能赢的走法,如果一个能赢的走法都没有,即 ,不管怎么走都是自己输,那么 。
- 如果 ,即下一步是后手走,那么只要 其中一个为 ,就可以判定 ,因为后手走到这一步时可以选择先手输的走法,如果一个先手输的走法都没有,即 ,不管怎么走都是先手赢,那么 。
求出 即可。
参考代码
#include<iostream>
#define ll long long
using namespace std;
const ll N=25;
ll n,m,sx,sy,d[4][2]={0,1,1,0,0,-1,-1,0},tx,ty;
char a[N][N];
bool vis[N][N],can;
bool in(ll x,ll y){return x>=1&&x<=n&&y>=1&&y<=m;}
bool check(ll x,ll y,ll step){
vis[x][y]=true;
ll nx,ny;
bool flag;
if(step%2){
for(ll i=0;i<4;++i){
nx=x+d[i][0],ny=y+d[i][1];
if(in(nx,ny)&&a[nx][ny]=='.'&&vis[nx][ny]==false){
flag=check(nx,ny,step+1);
if(!flag)return false;
}
}
}
else{
for(ll i=0;i<4;++i){
nx=x+d[i][0],ny=y+d[i][1];
if(in(nx,ny)&&a[nx][ny]=='.'&&vis[nx][ny]==false){
flag=check(nx,ny,step+1);
if(flag){
if(!step)tx=nx,ty=ny;
return true;
}
}
}
}
vis[x][y]=false;
return step%2;
}
int main(){
cin>>n>>m;
for(ll i=1;i<=n;++i){
for(ll j=1;j<=m;++j){
cin>>a[i][j];
if(a[i][j]=='S')sx=i,sy=j;
}
}
can=check(sx,sy,0);
if(can)cout<<"WIN"<<endl<<sx<<' '<<sy<<' '<<tx<<' '<<ty<<endl;
else cout<<"LOSE"<<endl;
return 0;
}
全部评论 6
希望获奖
6天前 来自 江苏
2IA旧依 )
依旧AI(
5天前 来自 重庆
1真不是我攻击你,你这个AI味太浓了
希望尽快紫衫,不然被ppl他们看见你就很危险了(
5天前 来自 重庆
1没
4天前 来自 江苏
1https://www.acgo.cn/discuss/study/64210
模仿这个排版的4天前 来自 江苏
1
%%%
5小时前 来自 广东
0顶
昨天 来自 江苏
0dddd
3天前 来自 浙江
0我就说T1咋这么眼熟,可我懒得搜题目
4天前 来自 浙江
0




















有帮助,赞一个