zoukankan      html  css  js  c++  java
  • 题解Codeforces Global Round 5 (CF1237)

    昨晚打的一场CF 感觉海星 写一下题解:

    A:送分题,先假设全部下取整求个和。如果>0就把一些负数变成上取整,如果<0就把一些正数变成上取整。

     1 #include<stdio.h>
     2 #define it register int
     3 #define il inline
     4 const int N=1000005;
     5 int a[N],n,b[N],sum;
     6 il void fr(int &num){
     7     num=0;char c=getchar();int p=1;
     8     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
     9     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    10     num*=p;
    11 }   
    12 int main(){ 
    13     fr(n);
    14     for(it i=1;i<=n;++i) fr(a[i]),b[i]=a[i]/2,sum+=b[i];
    15     if(!sum){
    16         for(it i=1;i<=n;++i) printf("%d
    ",b[i]);
    17         return 0;
    18     }
    19     for(it i=1;i<=n;++i)
    20         if(a[i]%2){
    21             if(a[i]<0&&sum>0) --b[i],--sum;
    22             if(a[i]>0&&sum<0) ++b[i],++sum;
    23         }
    24     for(it i=1;i<=n;++i)
    25         printf("%d
    ",b[i]);
    26     return 0;
    27 }
    View Code

    B:送分题,很明显只要前面比这个小的数的个数小于这个数在原序列中的编号,它就要罚款。树状数组随便写写好了。

     1 #include<stdio.h>
     2 #define it register int
     3 #define il inline
     4 const int N=1000005;
     5 int a[N],n,b[N],o,t[N],pos[N];
     6 il void fr(int &num){
     7     num=0;char c=getchar();int p=1;
     8     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
     9     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    10     num*=p;
    11 }   
    12 il void add(it x,it num){
    13     while(x<=N) t[x]+=num,x+=(x&-x);
    14 }
    15 il void cal(it x,int&now){
    16     now=0;
    17     while(x) now+=t[x],x-=(x&-x);
    18 }
    19 int main(){ 
    20     fr(n);
    21     for(it i=1;i<=n;++i) fr(a[i]),pos[a[i]]=i;
    22     for(it i=1,ans=0;i<=n;++i){
    23         fr(b[i]);
    24         cal(pos[b[i]],ans);
    25         if(ans<pos[b[i]]-1) ++o;
    26         add(pos[b[i]],1);
    27     }
    28     printf("%d",o);
    29     return 0;
    30 }
    View Code

    C:真的不知道简单和难的版本有啥区别。。每次把相同平面的排个序,然后在同一平面的先把x相同的两两相消,再把前后相消,然后把不同平面的上下相消。双倍经验拿好不送。

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #define it register int
     4 #define il inline
     5 using namespace std;
     6 const int N=100005;
     7 int n,cnt,tot;
     8 struct ky{
     9     int x,y,z,id;
    10 }a[N],o[N],tp[N],tpx[N];
    11 il bool cmp(ky p,ky q){
    12     return p.z<q.z;
    13 }
    14 il bool cmp2(ky p,ky q){
    15     return p.x^q.x?p.x<q.x:p.y<q.y;
    16 }
    17 il void fr(int &num){
    18     num=0;char c=getchar();int p=1;
    19     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
    20     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    21     num*=p;
    22 }   
    23 int main(){  
    24     fr(n);
    25     for(it i=1;i<=n;++i) fr(a[i].x),fr(a[i].y),fr(a[i].z),a[i].id=i; 
    26     sort(a+1,a+1+n,cmp);
    27     for(it i=1,j;i<=n;){
    28         cnt=0;for(j=i;j<=n&&a[j].z==a[i].z;++j) tp[++cnt]=a[j];
    29         sort(tp+1,tp+1+cnt,cmp2); 
    30         it now=0;
    31         for(it x=1,y;x<=cnt;){
    32             for(y=x;y<=cnt&&tp[y].x==tp[x].x;++y);
    33             if((y-x)&1) tpx[++now]=tp[x],++x;
    34             for(it tx=x;tx<y;tx+=2) printf("%d %d
    ",tp[tx].id,tp[tx+1].id);
    35             x=y;
    36         }
    37         if(now&1) o[++tot]=tpx[now],--now;
    38         for(it x=1;x<=now;x+=2)  printf("%d %d
    ",tpx[x].id,tpx[x+1].id);
    39         i=j;
    40     }
    41     for(it i=1;i<=tot;i+=2) printf("%d %d
    ",o[i].id,o[i+1].id);
    42     return 0;
    43 }
    View Code

    D:很显然只要循环两次以上就会造成死循环,手玩一下样例就行。然后开个三倍数组写个RMQ,每次算一下记一下这个点可以拓展的最远点,下次就从这个最远点开始往后拓展。

     1 #include<stdio.h>
     2 #include<math.h>
     3 #define it register int
     4 #define il inline
     5 using namespace std;
     6 const int N=1000005;
     7 int n,a[N],f[N][22],m,len[N];
     8 il int Max(it p,it q){
     9     return p>q?p:q;
    10 }
    11 il int Q(it l,it r){
    12     it k=log2(r-l+1);//printf("l=%d r=%d Q=%d
    ",l,r,Max(f[l][k],f[r-(1<<k)+1][k]));
    13     return Max(f[l][k],f[r-(1<<k)+1][k]);
    14 }
    15 il void fr(int &num){
    16     num=0;char c=getchar();int p=1;
    17     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
    18     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    19     num*=p;
    20 }   
    21 int main(){ 
    22     fr(n),m=n;
    23     for(it i=1;i<=n;++i) fr(a[i]),a[i+n]=a[i+n+n]=a[i],f[i][0]=f[i+n][0]=f[i+n+n][0]=a[i];
    24     n*=3;
    25     for(it j=1;(1<<j)<=n;++j)
    26         for(it i=1;i+(1<<j)-1<=n;++i)
    27             f[i][j]=Max(f[i+(1<<j-1)][j-1],f[i][j-1]);
    28     it l=1,r=1;
    29     for(it i=1;i<=m;++i){
    30         r=Max(r,i);
    31         while(r+1<=n&&a[r+1]*2>=Q(i,r)) ++r;
    32         len[i]=(r-i+1);
    33     }
    34     for(it i=1;i<=m;++i) printf("%d ",len[i]>2*m?-1:len[i]);
    35     return 0;
    36 } 
    View Code

    E:实际上只有0和1两种解。。那个mod998244353就是好玩的(或者说吓唬人的)。多画几种情况手算深入思考一下,对于每一种深度d只有x和x+1两个可能有解,那么我们就不断向上找直到有解。如果深度已经跳完了都找不到解就肯定无解啦。

     1 #include<stdio.h>
     2 #define it register int
     3 #define il inline
     4 int n,now=1;
     5 int main(){
     6     scanf("%d",&n);
     7     while(now<=n){
     8         if(now==n||now==n-1) return putchar('1'),0;
     9         now=(now&1)+(now<<1|1);
    10     }
    11     putchar('0');
    12     return 0;
    13 }
    View Code

    后面几题先咕咕咕(看似咕咕实则不会

  • 相关阅读:
    C#文件IO操作
    Microsoft Visual Studio Learning Pack 自动生成流程图插件(转)
    CSS之看穿绝对定位 absolute(转)
    Flex 图片缩放、托拽效果 Zoom版
    图标制作软件 Axialis IconWorkshop 6.50 汉化版
    Flex鼠标右键事件及菜单
    static 静态方法
    计算sql语句的执行时间
    正则表达式示例及总结
    结构/表现/行为完全分离的tab选项卡JS版(转)
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/11689906.html
Copyright © 2011-2022 走看看