YL 模拟赛总结 2
Problem
T1
我们知道,某数 \(x \bmod 9\) 的值 \(= x\) 各个数位上的数之和 \(\bmod \ 9\) 的值。
于是遍历 \([a,b]\),求出区间中每个数各个数位上的数之和 \(sum\),输出 \(sum \bmod 9\) 即可。
T2
中规中矩的 \(dp\)。
令 \(dp_{i,0}\) 表示第 \(i\) 个数填 \(0\) 时的方案数,\(dp_{i,1}\) 同理。
于是答案即为 \(dp_{i,0}+dp_{i,1}\)。
\(O(n)\) 预处理,转移方程:
然后 \(k\) 次询问每次 \(O(1)\) 回答即可。
代码:
#include<bits/stdc++.h> #define int long long using namespace std; const int MOD=12345; int n,k; int dp[100031][2]; signed main(){ cin>>n; dp[1][0]=dp[1][1]=1; for(int i=2;i<=100000;i++) dp[i][0]=(dp[i-1][0]+dp[i-1][1])%MOD, dp[i][1]=dp[i-1][0]%MOD; while(n--) cin>>k,cout<<(!k?0:(dp[k][0]+dp[k][1])%MOD)<<'\n'; return 0; }
T3
尝试以每个点为根,计算其散播的最小时间。
具体地,我们先对于当前的点向外扩展,然后将扩展到的点的最小时间压入优先队列。
然后:
对于这张图,点 \(x\) 向外扩展到了 \(x1,x2,x3\) 这三个点,分别在 \(1,2,3\) 的单位时间。
那么,为使每个点的时间尽可能少,我们应当将当前时间最大的点放在 \(x1\),次大的放在 \(x2\),最小的放在 \(x3\),这样就满足了上述条件。
于是我们在递归后将优先队列中的点一一取出,按照上述法则更新每个点的时间即可。
代码:
#include<bits/stdc++.h> using namespace std; int n,tot,ans=1e9; int out[1031],cost[1031]; vector<int> G[2031]; priority_queue<int> pq[1031]; void dfs(int x,int pre){ cost[x]=0; for(auto i:G[x]){ if(i==pre) continue; dfs(i,x); pq[x].push(cost[i]); } for(int i=1;!pq[x].empty();i++){ int now=pq[x].top(); pq[x].pop(); cost[x]=max(cost[x],now+i); } } int main(){ cin>>n; for(int i=2,v;i<=n;i++) cin>>v, G[i].push_back(v),G[v].push_back(i); for(int i=1;i<=n;i++){ dfs(i,i); int now_ans=-1e9; for(int j=1;j<=n;j++) now_ans=max(now_ans,cost[j]); if(now_ans+1<ans){ ans=now_ans+1; tot=0; memset(out,0,sizeof(out)); out[++tot]=i; } else if(now_ans+1==ans) out[++tot]=i; //cout<<now_ans<<'\n'; } cout<<ans<<'\n'; for(int i=1;i<=tot;i++) cout<<out[i]<<' '; return 0; }
T4
显然速度是具有单调性的,因此考虑二分答案。
check
函数的设计:
对于我们二分的速度值 \(k\),我们令图中一条边 \(e=(i,j)\) 的边权为 \(p_{i,j}-k \times t_{i,j}\)(即实际距离减理想距离),然后再这张图上跑 SPFA 最短路。
求出 \(dis\) 数组(单源最短路)后,若 \(dis_n \ge 0\),则说明还有某些路没跑完,速度值太小,令 \(l=mid\),否则令 \(r=mid\)。
若图存在负环,则速度变成无限大都跑不出去,于是一直令 \(l=mid\) 即可。
代码:
#include<bits/stdc++.h> using namespace std; int n; int p[131][131],t[131][131]; double w[131][131],dis[131]; int cnt[131]; bool vis[131]; bool spfa(){ queue<int> q; memset(dis,-0x3f3f3f3f,sizeof(dis)); memset(cnt,0,sizeof(cnt)); memset(vis,0,sizeof(vis)); q.push(1); dis[1]=0,vis[1]=cnt[1]=1; while(!q.empty()){ int u=q.front(); q.pop(),vis[u]=0; for(int v=1;v<=n;v++){ if(p[u][v]&&dis[v]<dis[u]+w[u][v]){ dis[v]=dis[u]+w[u][v]; if(!vis[v]){ cnt[v]++; if(cnt[v]>n) return 1; vis[v]=1; q.push(v); } } } } return dis[n]>=0; } bool check(double x){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) w[i][j]=p[i][j]-t[i][j]*x; return spfa(); } int main(){ cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>p[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>t[i][j]; double l=0.0,r=10000.0,eps=0.0001; while(l+eps<r){ double mid=(l+r)/2.0; if(check(mid)) l=mid; else r=mid; } cout<<setprecision(3)<<fixed<<l; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】