20170712训练赛比赛总结
来源:互联网 发布:linux 解压包指定目录 编辑:程序博客网 时间:2024/06/05 18:53
A
反思
- 虽然
AC 却花了70 多分钟。 - 我没有把问题想得透彻就开始敲代码
∗2 - 没有意义的二分
思考流程
- 发现题目的限制条件和提示条件
- 限制条件
- 两点间的边权为三维坐标中的最小值。
- 求最小生成树。
- 提示条件
- 我们可以把边都找出来有
3∗n 条边 - 分析一下有些的边是无效的
- 我们可以从这样一维的情况考虑
- 我们可以把边都找出来有
- 限制条件
- 分析一下我们发现对于一维的情况考虑,有效的边即为按
X 排序后每个相邻的两个点。 - 证明一下:
1−−−2−−−−3−−4 - 对于这样的三个点我们如果要连边
(1,3) 肯定是不优的,还不如以相同的代价来连(1,2) 和(2,3) 。
- 同理我们可以把这样的性质利用起来,造
3∗n 条边来造最小生成树即可。
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int M=1e5+5;struct P{int x,i;}X[M],Y[M],Z[M];struct E{ int x,y,c; bool operator<(const E&A)const{ return c<A.c; }}G[M*30];bool cmp(P A,P B){return A.x<B.x;}int n,fa[M],num;int find(int x){ if(x==fa[x])return x; return fa[x]=find(fa[x]);}ll solve(){ ll ans=0; int res=n-1; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=num;i++){ int x=G[i].x,y=G[i].y,c=G[i].c; if(find(x)==find(y))continue; else{ fa[find(x)]=find(y); res--; ans+=c; if(!res)return ans; } } if(res)return -1;}int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d %d %d",&X[i].x,&Y[i].x,&Z[i].x); Y[i].i=Z[i].i=X[i].i=i; } sort(X+1,X+1+n,cmp); sort(Y+1,Y+1+n,cmp); sort(Z+1,Z+1+n,cmp); for(int i=1;i<n;i++) G[++num]=(E){X[i].i,X[i+1].i,X[i+1].x-X[i].x}; for(int i=1;i<n;i++) G[++num]=(E){Y[i].i,Y[i+1].i,Y[i+1].x-Y[i].x}; for(int i=1;i<n;i++) G[++num]=(E){Z[i].i,Z[i+1].i,Z[i+1].x-Z[i].x}; sort(G+1,G+1+num); ll ans=solve(); printf("%lld",ans); return 0;}
B
反思
- 怎么简单的模拟题没有AC太不应该了!!!!!!
- 我没有把模拟的方法和复杂度想得透彻就开始敲代码
∗3
思考流程
- 没有什么可以说的。我们直接可以算出每个人个座位的距离,把它排序即可。
#include<bits/stdc++.h>using namespace std;const int M=50*50+5;char str[M][M];bool mark[M];int num_a,num_b,num,cnt[M],dis[M],n,m,ans;struct P{ int x,y; int operator+(const P&A)const{ return (A.x-x)*(A.x-x)+(A.y-y)*(A.y-y); }}A[M],B[M];struct E{ int a,b,c; bool operator <(const E &A)const{return c<A.c;}}G[M*M];int main(){ memset(dis,63,sizeof(dis)); scanf("%d %d",&n,&m); for(int i=0;i<n;i++)scanf("%s",str[i]); for(int i=0;i<n;i++)for(int j=0;j<m;j++){ if(str[i][j]=='X')A[++num_a]=(P){i,j}; if(str[i][j]=='L')B[++num_b]=(P){i,j}; } for(int i=1;i<=num_a;i++)for(int j=1;j<=num_b;j++)G[++num]=(E){i,j,A[i]+B[j]}; sort(G+1,G+num+1); for(int i=1;i<=num;i++){ int a=G[i].a,b=G[i].b,c=G[i].c; if(mark[a]||dis[b]<c)continue; dis[b]=c;mark[a]=1;cnt[b]++; } for(int i=1;i<=num_b;i++)if(cnt[i]>1)ans++; printf("%d\n",ans); return 0;}
阅读全文
1 0
- 20170712训练赛比赛总结
- 20170709训练赛比赛总结
- 20170711训练赛比赛总结
- FZU2203--比赛--10.1训练赛
- 3.20 ntr spoj比赛 训练总结 by mabodx
- 20170531练习赛比赛总结
- 20170606组队赛比赛总结
- 20170703练习赛比赛总结
- 20170702练习赛比赛总结
- 20170715离线赛比赛总结
- 20170723离线赛比赛总结
- 算法训练 比赛安排
- 算法训练 比赛安排
- 算法训练 比赛安排
- 比赛总结
- 比赛总结
- 比赛总结
- 比赛总结
- git使用简记-git分支使用
- 单项数据流
- springboot(2) rest项目起飞
- Redis cluster(八)-part 3
- Python学习
- 20170712训练赛比赛总结
- 淘宝网页白底蓝字显示不正常的修复办法
- rem、px、em之间的区别
- Java中的break和continue关键字使用
- Linux--crond和crontab学习
- Nodejs 利用passport完成本地认证 示例一
- 献给写作者的 Markdown 新手指南及语法
- 来电铃声和通话中的提示音
- java读取xml和xml写入数据