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

    如有错误,请指正,感谢!
  • 相关阅读:
    Flex4中panel拖拽
    jquery两边飘浮的对联广告
    javascript 无刷新上传图片之原理
    第十二周--servlet做一个逻辑处理!!!!!!!!!!!!!实现登录
    第十一周--邮件系统补充一个注册一个登陆验证码
    第十周--邮件系统全套(第二版)
    第九周--邮件系统2(全套增删改查)
    第八周-邮件系统1
    第七周JSP增删改查
    JSP第六周 还是session
  • 原文地址:https://www.cnblogs.com/scott527407973/p/9550280.html
Copyright © 2011-2022 走看看