zoukankan      html  css  js  c++  java
  • USACO 2016 US Open Contest, Gold解题报告

    1.Splitting the Field

    http://usaco.org/index.php?page=viewproblem2&cpid=645

    给二维坐标系中的n个点,求ans=用一个矩形覆盖所有点所用矩形面积-用两个矩形覆盖所有点所用两个矩形的最小面积和,而且两个矩形不能重合(边重合也不行)

    枚举两个矩形的分割线,也就是把所有点分成两个部分,枚举分割点;先预处理每个点之前和之后的最大,最低高度

    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 50015
    #define down(i,r,l) for(int i=r;i>=l;i--)
    #define rep(i,l,r) for(int i=l;i<=r;i++)
    using namespace std;
    typedef long long ll;
    int l[N],r[N],l1[N],r1[N],n;
    ll zs,ans;
    struct node{int x,y;}s[N];
    bool cmp(node x,node y) {return x.x==y.x?x.y<y.y:x.x<y.x;}
    void getans() { 
         ll now;
         sort(s+1,s+1+n,cmp);
         memset(l,60,(n+10)<<2); memset(l1,60,(n+10)<<2); memset(r,0,(n+10)<<2); memset(r1,0,(n+10)<<2);
         rep(i,1,n) l[i]=min(l[i-1],s[i].y),r[i]=max(r[i-1],s[i].y);
         down(i,n,1) l1[i]=min(l1[i+1],s[i].y),r1[i]=max(r1[i+1],s[i].y);
         rep(i,2,n) {
              now=(ll)(s[i-1].x-s[1].x) * (ll)(r[i-1]-l[i-1]) + (ll)(s[n].x-s[i].x) * (ll)(r1[i]-l1[i]); 
              ans=min(ans,now);
         }
    }
    int main () 
    {
         int miny,minx,maxx,maxy;
         miny=minx=1000000050,maxy=maxx=0;
         scanf("%d",&n); rep(i,1,n) 
         {
             scanf("%d%d",&s[i].x,&s[i].y),miny=min(miny,s[i].y),maxy=max(maxy,s[i].y);;
             maxx=max(maxx,s[i].x); minx=min(minx,s[i].x);
         }
         ans=(ll)(maxy-miny)*(ll)(maxx-minx),zs=ans;
         getans();
         rep(i,1,n) swap(s[i].x,s[i].y);
         getans(); 
         printf("%lld
    ",zs-ans);
    }

    2.Closing the Farm

    http://usaco.org/index.php?page=viewproblem2&cpid=646

    离线+并查集

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #define N 200020
    #include<vector>
    using namespace std;
    int n,m,a[N],f[N];
    bool vis[N],ok[N];
    vector<int>G[N];
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,a,b;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),f[i]=i;
        int cnt=0;
        for(int i=n;i;i--)
        {
            int u=a[i];
            cnt++;vis[u]=1;
            for(int j=0;j<G[u].size();j++)
            {
                int v=G[u][j];
                if(!vis[v])continue;
                int fa=find(u),fb=find(v);
                if(fa!=fb)
                {
                    if(fa>fb)swap(fa,fb);
                    f[fb]=fa;
                    cnt--;
                }
            }
            if(cnt==1)ok[i]=1;
        }
        for(int i=1;i<=n;i++)
            if(ok[i])printf("YES
    ");
            else printf("NO
    ");
    }

    3.248

    http://usaco.org/index.php?page=viewproblem2&cpid=647#

    给定一个长度为n的序列,初始元素值为1到40之间的整数,每次操作可以将两个相邻的并且大小相同
    的正整数替换成一个比原数大1的正整数。要求最大化最终数列中的最大值。
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int maxn=3e5+10;
    int n,ans,a,f[60][maxn];
    int main()
    {
          scanf("%d",&n);
          for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            f[a][i]=i+1;
        }
          for(int i=2;i<=58;i++)
               for(int j=1;j<=n;j++)
               {
                if(!f[i][j])f[i][j]=f[i-1][f[i-1][j]];
                 if(f[i][j])ans=max(i,ans);
               }
          printf("%d",ans);
          return 0;
    } 
  • 相关阅读:
    [APM] OneAPM 云监控部署与试用体验
    Elastic Stack 安装
    xBIM 综合使用案例与 ASP.NET MVC 集成(一)
    JQuery DataTables Selected Row
    力导向图Demo
    WPF ViewModelLocator
    Syncfusion SfDataGrid 导出Excel
    HTML Table to Json
    .net core 2.0 虚拟目录下载 Android Apk 等文件
    在BootStrap的modal中使用Select2
  • 原文地址:https://www.cnblogs.com/wisdom-jie/p/9309495.html
Copyright © 2011-2022 走看看