zoukankan      html  css  js  c++  java
  • UPC2018组队训练赛第六场

    题目来自UKIEPC2017


    A题:Alien Sunset

    有n个星球,输入每个星球一天的时间,日出和日落的时间。从日落到日出(包括日出、日落)是黑夜。其他的为白天。问在前1825天里能不能有一个时辰满足所有的星球都是夜晚。

    直接模拟

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 bool ap[200050];
     4 int main()
     5 {
     6     int n,hh;
     7     scanf("%d",&n);
     8     hh=0;
     9     int h,r,t;
    10     while(n--)
    11     {
    12         scanf("%d %d %d",&h,&r,&t);
    13         hh=max(h,hh);
    14         r++;
    15         t++;
    16         if(t<r)
    17         {
    18             for(int i=1;i<t;i++)
    19                 ap[i]=1;
    20             t=t+h;
    21         }
    22         int cnt;
    23         for(int i=r+1;i<=t-1;i++)
    24         {
    25             cnt=0;
    26             while(i+h*cnt<=183000)
    27             {
    28                 ap[i+h*cnt]=1;
    29                 cnt++;
    30             }
    31         }
    32     }
    33     for(int i=1;i<=hh*1825;i++)
    34         if(ap[i]==0)
    35         {
    36             printf("%d
    ",i-1);
    37             return 0;
    38         }
    39     printf("impossible
    ");
    40     return 0;
    41 }
    View Code

    B题:Breaking Biscuits

    给出一个二维多边形按逆时针方向的坐标,让该多边形的某一方向能放在一个长方形里,求该长方形的最小宽度。

    根据给出的点建立凸包,然后枚举凸包的每条边,计算凸包的其他点到该边的最大值,然后再找到这些最大值的最小值

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 struct Point        //定义点
     5 {
     6     double x,y;
     7     Point(double x=0,double y=0):x(x),y(y){}
     8 };
     9 typedef Point Vector;
    10 bool cmp(Point a,Point b)   //排序方式
    11 {
    12     return a.x<b.x||(a.x==b.x&&a.y<b.y);
    13 }
    14 Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}//重载减法号
    15 double Cross(Vector A,Vector B)
    16 {
    17     return A.x*B.y-A.y*B.x;
    18 }
    19 double Dot(Vector A,Vector B)
    20 {
    21     return A.x*B.x+A.y*B.y;
    22 }
    23 double Length(Vector A)
    24 {
    25     return sqrt(Dot(A,A));
    26 }
    27 int n;
    28 Point ch[200],p[200];
    29 int ConvexHull()    //凸包模板
    30 {
    31     sort(p,p+n,cmp);
    32     int m=0;
    33     for(int i=0;i<n;i++)
    34     {
    35         while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)  m--;
    36         ch[m++]=p[i];
    37     }
    38     int k=m;
    39     for(int i=n-2;i>=0;i--)
    40     {
    41         while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)  m--;
    42         ch[m++]=p[i];
    43     }
    44     if(n>1) m--;
    45     return m;
    46 }
    47 double Distance(Point P,Point A,Point B)    //点P到AB边的距离
    48 {
    49     Vector v1=B-A,v2=P-A;
    50     return fabs(Cross(v1,v2))/Length(v1);
    51 }
    52 int main()
    53 {
    54 //    freopen("in.txt","r",stdin);
    55 
    56     scanf("%d",&n);
    57     for(int i=0;i<n;i++)
    58     {
    59         scanf("%lf%lf",&p[i].x,&p[i].y);
    60     }
    61     int nn=ConvexHull();
    62     double maxn,minn=(double)1000000007;
    63     for(int i=1;i<nn;i++)       //枚举每条边
    64     {
    65         maxn=-1;
    66         if(i>1)
    67         {
    68             for(int j=0;j<i-1;j++)
    69             {
    70                 if(Distance(ch[j],ch[i],ch[i-1])>maxn)
    71                     maxn=Distance(ch[j],ch[i],ch[i-1]);
    72             }
    73         }
    74         for(int j=i+1;j<nn;j++)
    75         {
    76            if(Distance(ch[j],ch[i],ch[i-1])>maxn)
    77                 maxn=Distance(ch[j],ch[i],ch[i-1]);
    78         }
    79         if(maxn<minn)
    80             minn=maxn;
    81     }
    82     maxn=-1;
    83     for(int i=1;i<nn-1;i++)  //不要忘了ch[nn-1]ch[0]这条边
    84     {
    85         if(Distance(ch[i],ch[0],ch[nn-1])>maxn)
    86             maxn=Distance(ch[i],ch[0],ch[nn-1]);
    87     }
    88     if(maxn<minn)
    89         minn=maxn;
    90     printf("%.6lf
    ",minn);
    91     return 0;
    92 }
    View Code

    C题:Cued In

    直接模拟

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int a[10]={0};
     8     int n;
     9     cin>>n;
    10     string s;
    11     for(int i=0;i<n;i++)
    12     {
    13         cin>>s;
    14         if(s=="yellow")         a[2]++;
    15         else if(s=="green")     a[3]++;
    16         else if(s=="brown")     a[4]++;
    17         else if(s=="blue")      a[5]++;
    18         else if(s=="pink")      a[6]++;
    19         else if(s=="black")     a[7]++;
    20         else                    a[1]++;
    21     }
    22     int pos;
    23     for(int i=7;i>=1;i--)
    24     {
    25         if(a[i])
    26         {
    27             pos = i;
    28             break;
    29         }
    30     }
    31     int ans = 0;
    32     if(pos==1)
    33     {
    34         cout<<1<<endl;
    35         return 0;
    36     }
    37     else
    38         ans += (1+pos)*a[1];
    39 
    40     for(int i=pos;i>=2;i--)
    41         ans+=a[i]*i;
    42     cout<<ans<<endl;
    43     return 0;
    44 }
    View Code

    D题:Deranging Hat

    直接按照题目意思做

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 char s[1005];
     4 int main()
     5 {
     6     scanf("%s",s);
     7     int len=strlen(s);
     8     int a[100005],b[100005],cnt1=0;
     9     for(int i=0;i<len;i++)
    10     {
    11         for(int j=i+1;j<len;j++)
    12         {
    13             if(s[i]>s[j])
    14             {
    15                 a[cnt1]=i+1;
    16                 b[cnt1]=j+1;
    17                 cnt1++;
    18                 swap(s[i],s[j]);
    19             }
    20         }
    21     }
    22     for(int i=cnt1-1;i>=0&&i>=cnt1-10000;i--)
    23     {
    24         printf("%d %d
    ",b[i],a[i]);
    25     }
    26     return 0;
    27 }
    View Code

      

    E题:Education

    该题与原题输出不同,请注意!

    对于该题来说,直接写。

     1 #include <bits/stdc++.h>
     2  
     3 using namespace std;
     4  
     5 const int maxn = 5005;
     6  
     7 int main()
     8 {
     9     int n,m;
    10     cin>>n>>m;
    11     int a[maxn];
    12     int b[maxn];
    13     for(int i=0;i<n;i++)
    14         cin>>a[i];
    15     for(int i=0;i<m;i++)
    16         cin>>b[i];
    17     int x;
    18     for(int i=0;i<m;i++)
    19         cin>>x;
    20     sort(a,a+n);
    21     sort(b,b+m);
    22     int now = 0;
    23     for(int i=0;i<m;i++)
    24     {
    25         if(a[now]<=b[i])
    26             now++;
    27         if(now==n)
    28             break;
    29     }
    30     if(now==n)
    31     {
    32         cout<<"possible"<<endl;
    33         return 0;
    34     }
    35     else
    36     {
    37         cout<<"impossible"<<endl;
    38         return 0;
    39     }
    40     return 0;
    41 }
    View Code

    F题:Flipping Coins

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll; 
     4 double dp[405][405];
     5 int main()
     6 {
     7     int n,k;
     8     scanf("%d%d",&n,&k);
     9     dp[0][0] = 1;
    10     for(int i=0; i<k; i++)
    11     {
    12         for(int j=0; j<=n; j++)
    13         {
    14             if(dp[i][j]==0)
    15                 continue;
    16             if(n-j>=1)
    17             {
    18                 dp[i+1][j+1] += dp[i][j]*0.5;
    19                 dp[i+1][j] += dp[i][j]*0.5;
    20             }
    21             else
    22             {
    23                 dp[i+1][j] += dp[i][j]*0.5;
    24                 dp[i+1][j-1] += dp[i][j]*0.5;
    25             }
    26         }
    27     }
    28     double ans = 0;
    29     for(int i=1;i<=n;i++)
    30         ans+=dp[k][i]*i;
    31     printf("%.6f",ans);
    32     return 0;
    33 }
    View Code

    I题:I Work All Day

    求能产生最大余数的那个数

     1 #include <bits/stdc++.h>
     2  
     3 using namespace std;
     4 int n,h[100],t;
     5 int main()
     6 {
     7     scanf("%d",&n);
     8     for(int i=0;i<n;i++)
     9         scanf("%d",&h[i]);
    10     scanf("%d",&t);
    11     int tmp,pos,ans=3005;
    12     for(int i=0;i<n;i++)
    13     {
    14         tmp=t%h[i];
    15         if(tmp<ans)
    16         {
    17             ans=tmp;
    18             pos=i;
    19         }
    20     }
    21     printf("%d
    ",h[pos]);
    22     return 0;
    23 }
    View Code

    J题:Just A Minim

    直接按照题意写

     1 #include<bits/stdc++.h>
     2  
     3 using namespace std;
     4  
     5 int main()
     6 {
     7     int op,n;
     8     double ans=0;
     9     scanf("%d",&n);
    10     while(n--)
    11     {
    12         scanf("%d",&op);
    13         if(op==0)
    14         {
    15             ans+=2;
    16         }
    17         else
    18         {
    19             ans+=(double)1.0/(op*1.0);
    20         }
    21     }
    22     printf("%.6lf
    ",ans);
    23     return 0;
    24 }
    View Code

    L题:Lounge Lizards

    给出电视机的坐标,有n个人,分别输入他们的坐标和高度,可以把某些人赶出去,问最多能有多少人能看到电视

    首先求出每个人与电视机的方向向量,并约分,然后对于每组求LIS,最后取和

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 int n;
     6 const int inf=0x3f3f3f3f;
     7 const int maxn = 1e6+5;
     8 struct P
     9 {
    10     int x,y,h;
    11     ll dis;
    12 }a[maxn],o;
    13 int dp[maxn];
    14 int gcd(int a,int b)
    15 {
    16     return b?gcd(b,a%b):a;
    17 }
    18 bool cmp(P a,P b)
    19 {
    20     if(a.x!=b.x) return a.x<b.x;
    21     else if(a.y!=b.y) return a.y<b.y;
    22     else return a.dis<b.dis;
    23 }
    24 int f(int l,int r)      //O(nlog(n))的复杂度
    25 {
    26     int idx=1,where;
    27 //    for(int i=l;i<r;i++)  //初始化可加也不可加
    28 //        dp[i]=inf;
    29     dp[idx]=a[l].h;
    30     for(int i=l+1;i<r;i++)
    31     {
    32         if(a[i].h>dp[idx])
    33         {
    34             idx++;
    35             dp[idx]=a[i].h;
    36         }
    37         else
    38         {
    39             where=lower_bound(dp+1,dp+idx+1,a[i].h)-dp;
    40             dp[where]=a[i].h;
    41         }
    42     }
    43     return idx;
    44 }
    45 int main()
    46 {
    47     scanf("%d%d",&o.x,&o.y);
    48     scanf("%d",&n);
    49     for(int i=0; i<n; i++)
    50     {
    51         scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].h);
    52         a[i].x -= o.x;
    53         a[i].y -= o.y;
    54         a[i].dis = (ll)a[i].x*a[i].x + (ll)a[i].y*a[i].y; //注意要在每一项上加上(ll)
    55         int t = gcd(abs(a[i].x),abs(a[i].y));
    56         a[i].x/=t;
    57         a[i].y/=t;
    58     }
    59     sort(a,a+n,cmp);  //排序
    60     int j;
    61     int ans = 0;
    62     for(int i=0; i<n; i=j)
    63     {
    64         j = i+1;
    65         while(j<n&&a[i].x==a[j].x&&a[i].y==a[j].y)//求相同的方向向量
    66         {
    67             j++;
    68         }
    69         ans += f(i,j);  //求LIS
    70     }
    71     printf("%d
    ",ans);
    72     return 0;
    73 }
    View Code

    K题:Knightsbridge Rises

    拆点求最大流问题

    思路参考https://blog.csdn.net/V5ZSQ/article/details/80472491

    n个吊车拆成两排n个点,m个建筑物看作m个点

    1、源点向所有自身重量为0的吊车连容量为1的边

    2、每个吊车拆成的第一个点向第二个点连容量为1的边

    3、如果Li>=Wj,那么第i个吊车拆成的第二个点向第j个吊车拆成的第一个点连容量为1的边

    4、如果Li>=Tj,那么第i个吊车拆成的第二个点向第j个建筑物连容量为1的边

    5、每个建筑物向汇点连容量为1的边

    用最大流是否为m来判断是否所有建筑物都可以被吊起,然后再dfs,寻找路径

    代码参考 https://www.cnblogs.com/clrs97/p/7768748.html

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=300;
      4 const int maxe=4*maxn*maxn;
      5 const int inf=0x3f3f3f3f;
      6 #define MS(x,y) memset(x,y,sizeof(x))
      7 int head[maxn],tot,n,m;
      8 int w[maxe],cap[maxe],nxt[maxe];
      9 void add(int u,int v,int f) //存边
     10 {
     11     w[++tot]=v;
     12     cap[tot]=f;
     13     nxt[tot]=head[u];
     14     head[u]=tot;
     15 
     16     w[++tot]=u;
     17     cap[tot]=0;
     18     nxt[tot]=head[v];
     19     head[v]=tot;
     20 }
     21 int d[maxn],ST,ED;
     22 bool bfs()
     23 {
     24     MS(d,-1);
     25     queue<int>q;
     26     q.push(ST);
     27     d[ST]=0;
     28     while(!q.empty())
     29     {
     30         int u=q.front();q.pop();
     31         for(int i=head[u];i;i=nxt[i])
     32             if(cap[i])
     33             {
     34                 int v=w[i];
     35                 if(d[v]==-1)
     36                 {
     37                     d[v]=d[u]+1;
     38                     q.push(v);
     39                     if(v==ED)   return 1;
     40                 }
     41 
     42             }
     43     }
     44     return 0;
     45 }
     46 int dfs(int x,int all)
     47 {
     48     if(x==ED)   return all;
     49     int use=0;
     50     for(int i=head[x];i;i=nxt[i])   if(cap[i])
     51     {
     52         int y=w[i];
     53         if(d[y]==d[x]+1)
     54         {
     55             int tmp=dfs(y,min(cap[i],all-use));
     56             cap[i]-=tmp;
     57             cap[i^1]+=tmp;
     58             use+=tmp;
     59             if(use==all)    break;
     60         }
     61     }
     62     if(use==0)  d[x]=-1;
     63     return use;
     64 }
     65 int dinic()
     66 {
     67     int ret=0;
     68     while(bfs())    ret+=dfs(ST,inf);
     69     return ret;
     70 }
     71 vector<int>vt[maxn];
     72 void dfs_path(int cur,int x)  //寻找路径
     73 {
     74     for(int i=head[x];i;i=nxt[i]) if((i&1)&&cap[i])
     75     {
     76         x=w[i];
     77         break;
     78     }
     79     if(x==0)    return ;
     80     vt[cur].push_back(x-n);
     81     dfs_path(cur,x-n);
     82 }
     83 int W[maxn],L[maxn];
     84 int main()
     85 {
     86     scanf("%d",&n);
     87     MS(head,0);
     88     tot=1;
     89     ST=0;
     90     for(int i=1;i<=n;i++)
     91     {
     92         scanf("%d%d",&W[i],&L[i]);
     93         if(W[i]==0)
     94             add(ST,i,1);
     95         add(i,n+i,1);
     96     }
     97     for(int i=1;i<=n;i++)
     98     {
     99         for(int j=1;j<=n;j++)   if(i!=j&&L[i]>=W[j])
    100         {
    101             add(n+i,j,1);
    102         }
    103     }
    104     scanf("%d",&m);
    105     ED=2*n+m+1;
    106     int xx;
    107     for(int i=1;i<=m;i++)
    108     {
    109         scanf("%d",&xx);
    110         add(2*n+i,ED,1);
    111         for(int j=1;j<=n;j++)   if(L[j]>=xx)
    112         {
    113             add(n+j,2*n+i,1);
    114         }
    115     }
    116     if(dinic()==m)
    117     {
    118         for(int i=head[ED];i;i=nxt[i])  if((i&1)&&cap[i])
    119         {
    120             vt[w[i]-2*n].clear();
    121             dfs_path(w[i]-2*n,w[i]);
    122         }
    123         for(int i=1;i<=m;i++)
    124         {
    125             for(int j=vt[i].size()-1;j>=0;j--)
    126             {
    127                 if(j!=vt[i].size()-1)   printf(" ");
    128                 printf("%d",vt[i][j]);
    129             }
    130             printf("
    ");
    131         }
    132     }
    133     else
    134         printf("impossible
    ");
    135     return 0;
    136 
    137 }
    View Code

    如有错误,请指正,感谢!
  • 相关阅读:
    .NetCore Grpc 客服端 工厂模式配置授权
    DOCKER 拉取 dotnet 镜像太慢 docker pull mcr.microsoft.com too slow
    Introducing .NET 5
    VSCode 出现错误 System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached.
    Omnisharp VsCode Attaching to remote processes
    zookeeper3.5.5 centos7 完全分布式 搭建随记
    Hadoop2.7.7 centos7 完全分布式 配置与问题随记
    MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序
    SQL基础随记3 范式 键
    MySQL调优 优化需要考虑哪些方面
  • 原文地址:https://www.cnblogs.com/scott527407973/p/9550280.html
Copyright © 2011-2022 走看看