zoukankan      html  css  js  c++  java
  • 2017.09.03校内训练

    T1:卡片

    题解:这很明显,是一道选择题!!!

    我们考虑每一种情况:只有一种卡片时,很显然最后剩下的只能是这一种;有三种卡片时,可以变成各只有一张,无论选取哪两张,都可以变成剩下的那一张,因此每一种都可以剩下;有两种的情况:若这两种都有两张以上,便可以各取一张合成没有的那一种,最后结果请参见上一条;若有一种只有一张,另一种有多张,则每一次的转化操作都要使用到较多的那种一张,不论如何都不可能合成较多张的那一种。因此结果是除了多于一张的那一种以外的其它两种;若这两种各只有一张,则结果必定是没有的那一种。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 struct node{
     9     char ki;
    10     int num;
    11 }card[5];
    12 int n,kind=0;
    13 bool c[5]={};
    14 char s[210];
    15 int main(){
    16     freopen("card.in","r",stdin);
    17     freopen("card.out","w",stdout);
    18     scanf("%d",&n);
    19     scanf("%s",s);
    20     int i,j;
    21     card[1].ki='B';card[2].ki='G';card[3].ki='R';
    22     card[1].num=0;card[2].num=0;card[3].num=0;
    23     int x;
    24     for(i=0;i<n;++i){
    25         if(s[i]=='B')  x=1;
    26         if(s[i]=='G')  x=2;
    27         if(s[i]=='R')  x=3;
    28         if(card[x].num==0)  kind++;
    29         card[x].num++;
    30     }
    31     if(kind==3){
    32         printf("BGR\n");
    33         return 0;
    34     }
    35     if(kind==1){
    36         if(card[1].num>0)  printf("B\n");
    37         if(card[2].num>0)  printf("G\n");
    38         if(card[3].num>0)  printf("R\n");
    39         return 0;
    40     }
    41     if(kind==2){
    42         int a,b;
    43         if(card[1].num>0){
    44             a=1;
    45             if(card[2].num>0)  b=2;
    46             else  b=3;
    47         }
    48         else{
    49             a=2;b=3;
    50         }
    51         if(card[a].num>=2 && card[b].num>=2){
    52             printf("BGR\n");
    53             return 0;
    54         }
    55         if(card[a].num==1 && card[b].num==1){
    56             for(i=1;i<=3;++i){
    57                 if(card[i].num==0){
    58                     printf("%c\n",card[i].ki);
    59                     return 0;
    60                 }
    61             }
    62         }
    63         for(i=1;i<=3;++i){
    64             if(card[i].num<=1)  c[i]=true;
    65         }
    66         for(i=1;i<=3;++i){
    67             if(c[i]==true){
    68                 printf("%c",card[i].ki);
    69             }
    70         }
    71         printf("\n");
    72     }
    73     return 0;
    74 }
    card.cpp

     T2:取数

    题解:我们注意到:取奇数个数的数一定不会比再取一个偶数的结果更劣。而计算平均数的复杂度很高。因此我们考虑枚举中位数。而取一个中位数,在一个递增序列中,它左边的数应当尽量靠近它,右边的数应当尽量远离它。因此我们由题目可以得出:可以对于每一个位置三分这个位置的最优解/较优解并更新答案即可。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstring>
     7 #define ll long long
     8 using namespace std;
     9 int n;
    10 ll maxw,maxl,l,r,wa,wb;
    11 int a[200010];
    12 ll pre[200010];
    13 double va,vb,v,ans=-1;
    14 double getans(int w,int l){
    15     ll sum=0;
    16     sum+=pre[w]-pre[w-l-1];
    17     sum+=pre[n]-pre[n-l];
    18     return (double)sum/(double)(2*l+1)-(double)a[w];
    19 }
    20 int main(){
    21     freopen("win.in","r",stdin);
    22     freopen("win.out","w",stdout);
    23     scanf("%d",&n);
    24     int i,j,k;
    25     for(i=1;i<=n;++i){
    26         scanf("%d",&a[i]);
    27     }
    28     sort(a+1,a+n+1);
    29     pre[0]=0;
    30     for(i=1;i<=n;++i){
    31         pre[i]=pre[i-1]+a[i];
    32     }
    33     if(n<=2){
    34         printf("0.00\n");return 0;
    35     }
    36     for(i=1;i<=n;++i){
    37         l=0;r=min(i-1,n-i);
    38         while(l+1<=r){
    39             wa=l+(r-l)/3;
    40             wb=r-(r-l)/3;
    41             va=getans(i,wa);
    42             vb=getans(i,wb);
    43             if(va>vb){
    44                 r=wb-1;
    45             }
    46             else  l=wa+1;
    47         }
    48         v=getans(i,l);
    49         if(v>ans){
    50             ans=v;
    51             maxw=i;
    52             maxl=l;
    53         }
    54     }
    55     printf("%.2lf",ans);
    56     return 0;
    57 }
    win.cpp

    T3:密码

    题解:我们注意到,因为可能出现的密码种类只有10000种。所以我们先用O(10L)的时间来预处理出对于每一位向后的第一个某数字的位置。之后在O(10000)的时间内枚举密码,对于每一个密码,可以在O(n)的时间里check,最后统计进模板里即可。

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 char ch[1000010];
     9 int l[1010];
    10 int n,a,b;
    11 int f[1000010][20]; 
    12 int main(){
    13     freopen("key.in","r",stdin);
    14     freopen("key.out","w",stdout);
    15     int i,w,h,z,j;
    16     scanf("%d",&n);
    17     l[0]=0;
    18     for(i=1;i<=n;++i){
    19         scanf("%d%s",&l[i],ch+l[i-1]);
    20         l[i]+=l[i-1];
    21     }
    22     for(i=0;i<=9;++i)  f[l[n]][i]=l[n];
    23     for(i=l[n]-1;i>=0;--i){
    24         memcpy(f[i],f[i+1],sizeof f[i+1]);
    25         f[i][ch[i]-48]=i;
    26     }
    27     a=0;b=0;
    28     for(w=0;w<=9;++w){
    29         for(h=0;h<=9;++h){
    30             for(z=0;z<=9;++z){
    31                 for(j=0;j<=9;++j){
    32                     for(i=0;i<n;++i){
    33                         if(f[f[f[f[l[i]][w]][h]][z]][j]<l[i+1])  ++a;
    34                         else  break ;
    35                     }
    36                     b+=a/n;a=0;
    37                 }
    38             }
    39         }
    40     }
    41     printf("%d\n",b);
    42     return 0;
    43 }
    key.cpp

    T4:三角之恋

    题解:我们可以从题目中看出这些信息:由于我们所要加入平面中的三角形都是等腰直角三角形,因此对于每一个单位长度的正方形,若其被覆盖,则只会存在两种情况:完全覆盖与过对角线覆盖一半。因此我们考虑采用离散化+扫描线的方式做。

          首先我们需要离散每个三角形的(x,y),(x+m,y),(x,y+m)三个点,便于后面计算答案。

          然后我们将每个三角形记作一个只有底部线段,并且右端点不断向左端点缩小的线段。在更新时直接暴力排序并且剔除会被某个其他线段覆盖的线段,然后将y坐标不断向上推,在过程中暴力计算每个离散长方形的面积,如果某个长方形没有被完全覆盖,那么就减去没覆盖的部分的面积。这样就可以在O(n2)的时间复杂度内计算出答案。

    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cmath>
      7 #define ll long long
      8 using namespace std;
      9 struct node{
     10     int x,y,m,xb,tx,ty;
     11 }tri[5010];
     12 int n,lx,ly,ls,th;
     13 int x[10010],y[10010];
     14 node s[10010];
     15 bool u[10010];
     16 ll ans;
     17 bool cmp(node a,node b){
     18     if(a.y!=b.y)  return a.y<b.y;
     19     if(a.x!=b.x)  return a.x<b.x;
     20     return a.tx<b.tx;
     21 }
     22 void work(){
     23     int to=y[th+1]-y[th],r;
     24     int i,j=1;
     25     for(i=s[1].x;x[i]<=s[ls].xb;++i){
     26         while(j<ls && i>=s[j+1].x)  ++j;
     27         if(x[i]>=s[j].xb)  continue ;
     28         r=min(x[i+1],s[j].xb);
     29         ans+=2LL*(r-x[i])*to;
     30         if(r>s[j].xb-to){
     31             if(x[i]<s[j].xb-to){
     32                 int l=r-(s[j].xb-to);
     33                 ans-=(ll)l*l;
     34             }
     35             else{
     36                 ans-=(ll)(r-x[i])*(r-x[i]);
     37                 int l=x[i]-(s[j].xb-to);
     38                 ans-=2LL*l*(r-x[i]);
     39             }
     40         }
     41     }
     42     th++;
     43     for(i=1;i<=ls;++i){
     44         if(s[i].ty<=th)  u[i]=false;
     45         else{
     46             u[i]=true;
     47             s[i].xb=x[s[i].tx]-(y[th]-y[s[i].y]);
     48         }
     49     }
     50     int k=ls;ls=0;
     51     for(i=1;i<=k;++i){
     52         if(u[i])  s[++ls]=s[i];
     53     }
     54 }
     55 int main(){
     56     freopen("tri.in","r",stdin);
     57     freopen("tri.out","w",stdout);
     58     scanf("%d",&n);
     59     int i,j,k;
     60     for(i=1;i<=n;++i){
     61         scanf("%d%d%d",&tri[i].x,&tri[i].y,&tri[i].m);
     62         x[++lx]=tri[i].x;x[++lx]=tri[i].x+tri[i].m;
     63         y[++ly]=tri[i].y;y[++ly]=tri[i].y+tri[i].m;
     64     }
     65     sort(x+1,x+lx+1);sort(y+1,y+ly+1);
     66     lx=unique(x+1,x+lx+1)-x-1;
     67     ly=unique(y+1,y+ly+1)-y-1;
     68     y[ly+1]=2e9;x[lx+1]=2e9;
     69     for(i=1;i<=n;++i){
     70         tri[i].tx=lower_bound(x+1,x+lx+1,tri[i].x+tri[i].m)-x;
     71         tri[i].ty=lower_bound(y+1,y+ly+1,tri[i].y+tri[i].m)-y;
     72         tri[i].x=lower_bound(x+1,x+lx+1,tri[i].x)-x;
     73         tri[i].y=lower_bound(y+1,y+ly+1,tri[i].y)-y;
     74         tri[i].xb=x[tri[i].tx];
     75     }
     76     sort(tri+1,tri+n+1,cmp);
     77     tri[n+1].y=ly+1;
     78     ls=1;s[ls]=tri[1];th=tri[1].y;s[0].xb=-2e9;
     79     for(i=2;i<=n+1;++i){
     80         while(ls && tri[i].y>th)  work();
     81         if(th<tri[i].y)  th=tri[i].y;
     82         bool found=false;
     83         for(j=1;j<=ls;++j){
     84             if(tri[i].x<s[j].x){
     85                 if(tri[i].xb<=s[j-1].xb)  break ;
     86                 for(k=ls;k>=j;--k)  s[k+1]=s[k];
     87                 s[j]=tri[i];
     88                 int lr=ls+1;ls=j;
     89                 for(k=j+1;k<=lr;++k){
     90                     if(s[k].xb>s[j].xb)  s[++ls]=s[k];
     91                 }
     92                 found=true;
     93             }
     94         }
     95         if(!found && tri[i].xb>s[ls].xb)  s[++ls]=tri[i];
     96     }
     97     if(ans&1){
     98         printf("%lld.5",ans/2);
     99     }
    100     else  printf("%lld.0",ans/2);
    101     return 0;
    102 }
    tri.cpp
  • 相关阅读:
    微信小程序中showToast 提示
    微信小程序传code 拿token 后台报40029 状态吗,是为什么?
    双语开发思路
    input的number类型只能输入正数,禁止负数输入
    css全站字体,中文英文不同,粗细统一
    截取字符,超出的用省略号代替js实现 substring
    导航切换悬浮最上层
    VUE常用写法
    支付问题回调跳不过去问题
    窗口打开方式
  • 原文地址:https://www.cnblogs.com/lazytear/p/7473244.html
Copyright © 2011-2022 走看看