20170712训练赛比赛总结

来源:互联网 发布:linux 解压包指定目录 编辑:程序博客网 时间:2024/06/05 18:53

A

反思

  • 虽然AC却花了70多分钟。
  • 我没有把问题想得透彻就开始敲代码2
  • 没有意义的二分

思考流程

  • 发现题目的限制条件提示条件
    • 限制条件
      • 两点间的边权为三维坐标中的最小值。
      • 求最小生成树。
    • 提示条件
      • 我们可以把边都找出来有3n条边
      • 分析一下有些的边是无效的
      • 我们可以从这样一维的情况考虑
  • 分析一下我们发现对于一维的情况考虑,有效的边即为按X排序后每个相邻的两个点。
  • 证明一下:
    • 1234
    • 对于这样的三个点我们如果要连边1,3肯定是不优的,还不如以相同的代价来连1,22,3
  • 同理我们可以把这样的性质利用起来,造3n条边来造最小生成树即可。
#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;}
原创粉丝点击