【好题总结】atcoder好题选做

本文作者分享了在AtCoder平台遇到的一些具有挑战性的题目,包括ARC083 F Collecting Balls、ARC 098F、ARC 077F等。通过对这些问题的解析,作者介绍了模型转化、经典算法应用等解题技巧,并总结了每道题目的关键思路。文章还包含了作者在解题过程中的感悟,如转化成图论模型、二分图匹配、循环节的求解等,强调了思考和细节的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习ShichengXiao’s的笔记

一下是还没有写的题
ARC083 F Collecting Balls 感觉好难写

以下是简单的小结和感想(建议看原文,更加完整和详细,下文有很大一部分也是来自原文)
ARC083 F Collecting Balls

题意
在一个平面内共有 2n 个球,保证这 2n 个球均在第一象限,给定每个球的坐标。此外坐标轴上共有 2n 个机器人。每个机器人的位于 (1,0),(2,0),⋯,(n,0),(0,1),(0,2),⋯,(0,n) 。每个机器人会沿着垂直于坐标轴的方向行走,直到遇到一个球,就会将这个球拿走,机器人也会消失。如果没有遇到球,机器人也会消失。问有多少种不同的机器人收集球的顺序,满足所有球都被收集。
n≤1e5 。

技巧
模型的转化,经典模型的运用。转化成图论模型,连边定拓扑序

题解
考虑每个球会被哪个机器人收集,这样就可以建出一个二分图。由于一个球恰好只有两条出边,所以可以类似于原来讲过的某题的思路,将这两个机器人之间连一条边,每条边只能被它相连的两个点选择。容易发现,如果最后是有解的,那么这张新图一定是一个基环树森林。回到原题,原题除了需要确定每个球被谁拿走之外,还需要求满足条件的排列个数。对于某个点而言,与这个点相连的某一条边可以被这个点选择,当且仅当与这个点相连的所有未选择的点,权值均大于这个被选择的点。
考虑树边,容易发现树边被哪个点选择一定是确定的。当一个点可选择的点在它的邻边中可选择第k大的时候,把该点和1-k-1大连有向边,限制选择的先后顺序。
画图可以发现,这个条件是充要的。
注意必须要求拓扑序,因为很多限制互相影响,无法直接算方案数
考虑环上的边,容易发现,我们只需要给定一个顺逆时针的顺序,那么每条边被哪个点选择也是确定的。接下来考虑顺序问题。
之后就是一个有向树森林的拓扑序个数问题

总结
思路很经典,也很巧
一开始没想到求拓扑序,加上后发现特别长
把两个图的边区分开
找基环树的环的时候,如果找到环return,那么联通块包含的点需要另找
一下子用来两小时写这题,和预计的半小时差得好远!----因为dfs边用混了WA大样例,没有看出代码错误,调了1一小时。
静下来再仔细一点,是可以发现错误的

code

ARC 098F

找性质,定经过顺序,然后DP
注意要把多的贡献的定义搞清楚。因为知道了选点的先后顺序,可以dfs递归其他联通块。然而是不能直接暴力dfs的,因为这不是点分,每次找根不是重心,直接dfs会TLE。
还要注意每个联通块的根不是直接和上一层根相连的点。
可以倒过来做,每次合并,用并查集维护,更加好写。
根据定义,每个联通块的根的多花的钱一定更多,所以DP的时候只需要考虑这个多出的贡献是否可能减小。

my code

ARC 077F

题意
定义一个串为偶串,当且仅当这个串长度为偶数,且前后两半完全相同。对于一个给定的字符串 S,定义一个函数 f(S) 表示将字符串 S 后添加一个非空字符串 T,满足新串是一个偶串,且 |T| 尽可能小。求 f(∞)(S) 第 l 个字符到第 r 个字符,每种字母的出现次数。f(n)(x) 表示将函数 f(x) 迭代 n 次。
l,r≤1e18,|S|≤2e5 且 S 为一个偶串。

题解
由于原串一定为一个偶串,我们设原串为 SS 。不妨设 S 的最短循环节为 T ,那么可以得到 f(SS)&

### AtCoder 平台经典或高质量编程竞赛目推荐 #### 动态规划类目 对于动态规划这一重要算法领域,在 AtCoder 上有多个值得尝试的经典问。例如「ABC148_D Grid 1」是一个典型的二维网格路径计数问,通过构建状态转移方程来解决此类问能够很好地锻炼手的状态设计能力[^1]。 ```cpp #include <bits/stdc++.h> using namespace std; const int MOD = 1e9+7; int main() { long H, W; cin >> H >> W; vector<vector<long>> dp(H+1,vector<long>(W+1)); dp[1][1]=1; for(int i=1;i<=H;++i){ string s;cin>>s; for(int j=1;j<=W;++j){ if(s[j-1]=='#') continue; if(i>1) (dp[i][j]+=dp[i-1][j])%=MOD; if(j>1) (dp[i][j]+=dp[i][j-1])%=MOD; } } cout<<dp[H][W]<<endl; } ``` #### 数据结构优化类目 涉及复杂数据处理与高效查询的数据结构也是比赛热点之一。「AGC038_C Minimize The Difference」要求最小化数组差值绝对值之和的最大值,这道巧妙运用了堆这种优先队列实现贪心策略下的最优解求取过程。 ```cpp #include<bits/stdc++.h> #define rep(i,n)for(int i=0;i<(n);++i) using namespace std; typedef pair<int,int>P; priority_queue<P,vector<P>,greater<P>>que; vector<int>v[2]; bool used[2][50]; void solve(){ int n,k,a,b,c,d,e,f,g,h,i,j,m,p,q,r,s,t,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; char c1,c2,c3,c4; double aa,bb,cc,dd,ee,ff,gg,hh,ii,jj,kk,ll,mm,nn,oo,pp,qq,rr,ss,tt,uu,vv,ww,xx,yy,zz,AA,BB,CC,DD,EE,FF,GG,HH,II,JJ,KK,LL,MM,NN,OO,PP,QQ,RR,SS,TT,UU,VV,WW,XX,YY,ZZ; string str,str1,str2,str3,str4; cin>>N>>M; v[0].resize(N); v[1].resize(M); rep(i,N)cin>>v[0][i]; rep(i,M)cin>>v[1][i]; sort(v[0].begin(),v[0].end()); sort(v[1].begin(),v[1].end()); memset(used,false,sizeof(used)); rep(i,min(N,M)){ que.push(P(abs(v[0][i]-v[1][i]),i)); used[0][i]=true; used[1][i]=true; } while(!que.empty()){ P p=que.top();que.pop(); a=p.second; b=a<N?a:a-N; if(b==N||b==M)continue; if(!used[0][b]){ que.push(P(abs(v[0][b]-v[1][(a)%M]))); used[0][b]=true; }else{ que.push(P(abs(v[0][(a)%N]-v[1][b]))); used[1][b]=true; } } printf("%d\n",que.top().first); } signed main(){solve();} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值