zoukankan      html  css  js  c++  java
  • noip模拟测试16


    T1:Blue

      贪心就完了,显然一只蛤尽量往远跳是最优的,用每次跳跃跨过的石头数更新答案就完了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cstdlib>
     7 using namespace std;
     8 const int MAXN=1000005,INF=0x3f3f3f3f;
     9 int T;
    10 int n,m,d,L,a[MAXN],ans;
    11 inline int R() {
    12     int a=0;char c=getchar();
    13     while(c>'9'||c<'0')c=getchar();
    14     while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar();
    15     return a;
    16 }
    17 bool flag;
    18 int main() {
    19     T=R();
    20     while(T--) {
    21         n=R();m=R();d=R();L=R();
    22         for(int i=1;i<=n;i++) a[i]=R();
    23         a[0]=0;a[n+1]=L;ans=m;
    24         int now=0;
    25         for(int i=0;i<=n+1;i++) {
    26             while(now!=n+1&&a[now+1]-a[i]<=d) ++now;
    27             if(i==now) {
    28                 printf("0
    "),flag=1;
    29                 break;
    30             }
    31             if(now==n+1) break;
    32             ans=min(ans,now-i);
    33         }
    34         if(!flag) {
    35             if(ans==m) printf("Excited
    ");
    36             else printf("%d
    ",ans);
    37         }
    38         flag=0;
    39     }
    40     return 0;
    41 }
    t1 Code


    T2:Weed

      用线段树维护操作序列,难点在pushup怎么写,考虑每个节点维护三个信息:

      还能删几层,还剩几层,剩下的高度和

      前两个信息可以通过简单的判断$O(1)$计算

      第三个信息可以向下递归计算,具体实现看代码的ask函数

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<cstdlib>
    using namespace std;
    const int MAXN=300005;
    int m,q;
    struct opt {
        int k,v;
    }o[MAXN];
    struct node {
        int l,r,sum,c,e;
    }tr[MAXN*4];
    int ask(int p,int e) {
        if(e==tr[p<<1|1].c) return tr[p].sum-tr[p<<1|1].sum;
        if(e<tr[p<<1|1].c) return tr[p].sum-tr[p<<1|1].sum+ask(p<<1|1,e);
        return ask(p<<1,e-tr[p<<1|1].c+tr[p<<1|1].e);
    }
    void up(int p) {
        if(tr[p<<1|1].e>=tr[p<<1].c) {
            tr[p].e=tr[p<<1].e+tr[p<<1|1].e-tr[p<<1].c;
            tr[p].c=tr[p<<1|1].c;
            tr[p].sum=tr[p<<1|1].sum;
        } else if(!tr[p<<1|1].e) {
            tr[p].c=tr[p<<1].c+tr[p<<1|1].c;
            tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
            tr[p].e=tr[p<<1].e;
        } else {
            tr[p].e=tr[p<<1].e;
            tr[p].c=tr[p<<1|1].c+tr[p<<1].c-tr[p<<1|1].e;
            tr[p].sum=tr[p<<1|1].sum+ask(p<<1,tr[p<<1|1].e);
        }
    }
    void build(int p,int l,int r) {
        tr[p].l=l,tr[p].r=r;
        if(l==r) {
            tr[p].sum=o[l].k?0:o[l].v;
            tr[p].c=o[l].k?0:1;
            tr[p].e=o[l].k?o[l].v:0;
            return;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid+1,r);
        up(p);
    }
    void change(int p,int x,int k,int c) {
        if(tr[p].l==tr[p].r) {
            tr[p].sum=k?0:c;
            tr[p].c=k?0:1;
            tr[p].e=k?c:0;
            return;
        }
        int mid=(tr[p].l+tr[p].r)>>1;
        if(x<=mid) change(p<<1,x,k,c);
        else change(p<<1|1,x,k,c);
        up(p);
    }
    int main() {
        scanf("%d%d",&m,&q);
        for(int i=1;i<=m;i++) scanf("%d%d",&o[i].k,&o[i].v);
        build(1,1,m);
        for(int i=1,aa,bb,cc;i<=q;i++) {
            scanf("%d%d%d",&aa,&bb,&cc);
            change(1,aa,bb,cc);
            printf("%d
    ",tr[1].sum);
        }
        return 0;
    }
    t2 Code

    ps:一道相似的题——楼房重建



    T3:Drink

      链表神题

      对于每个点(可以看做一个人),规定一个正方向(面朝哪边)

      并记录在这个方向下该点的前后左右分别是那些点

      (以这个人的视角看他的前后左右分别是谁)

      对于一次修改来说,只需要修改正方形边界上人的信息

      注意,不需要也不能记录每个人的方向,因为这样会使修改的复杂度降至$O(n^2)$

      只能记录某一个人(比如左上角)的方向和编号

      再用前后左右的信息推出其他人的方向

      1 #include<cmath>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<cstdlib>
      7 #include<queue>
      8 #include<vector>
      9 using namespace std;
     10 const int MAXN=2005;
     11 int n,m,q,s[MAXN][MAXN];
     12 /*
     13       0
     14     3 x 1
     15       2
     16 */
     17 struct Point {
     18     int id;
     19     Point() {id=0;}
     20     int x() {
     21         return (id-1)/m+1;
     22     }
     23     int y() {
     24         return (id-1)%m+1;
     25     }
     26 }fp,tmp[8][MAXN];
     27 int fd,tmpd[8][MAXN];
     28 bool operator == (const Point &aa,const Point &bb) {
     29     return aa.id==bb.id;
     30 }
     31 Point New(int _x,int _y) {
     32     Point ret;
     33     ret.id=(_x-1)*m+_y;
     34     return ret;
     35 }
     36 struct Node {
     37     Point p[4];
     38 }a[MAXN][MAXN];
     39 inline int my_d(int d,int opt) {
     40     return (opt-d+4)%4;
     41 }
     42 Point get_p(Point p,int d,int opt) {
     43     //面向d的点p的opt方向的点
     44     return a[p.x()][p.y()].p[my_d(d,opt)];
     45 }
     46 int get_d(Point lp,Point p,int d,int opt) {
     47     //面向d的点lp的opt方向的点p的方向
     48     int topt=(opt+2)%4;
     49     for(int i=0;i<4;i++)
     50         if(get_p(p,i,topt)==lp) return i;
     51     return -1;
     52 }
     53 void move(Point &p,int &d,int opt) {
     54     Point tp=p;
     55     p=get_p(p,d,opt);
     56     d=get_d(tp,p,d,opt);
     57 }
     58 void modify(Point p,int d,Point c) {
     59     //将p点的d方向上的点改为c
     60     a[p.x()][p.y()].p[d]=c;
     61 }
     62 void change(int x,int y,int c) {
     63     Point np=fp;
     64     int nd=fd;
     65     for(int i=1;i<x;i++) move(np,nd,2);
     66     for(int i=1;i<y;i++) move(np,nd,1);
     67     for(int i=1;i<=c;move(np,nd,1),++i) {
     68         tmp[0][i]=np,tmp[4][i]=get_p(np,nd,0);
     69         tmpd[0][i]=nd,tmpd[4][i]=get_d(np,tmp[4][i],nd,0);
     70     }
     71     move(np,nd,3);
     72     for(int i=1;i<=c;move(np,nd,2),++i) {
     73         tmp[1][i]=np,tmp[5][i]=get_p(np,nd,1);
     74         tmpd[1][i]=nd,tmpd[5][i]=get_d(np,tmp[5][i],nd,1);
     75     }
     76     move(np,nd,0);
     77     for(int i=1;i<=c;move(np,nd,3),++i) {
     78         tmp[2][i]=np,tmp[6][i]=get_p(np,nd,2);
     79         tmpd[2][i]=nd,tmpd[6][i]=get_d(np,tmp[6][i],nd,2);
     80     }
     81     move(np,nd,1);
     82     if(x==1&&y==1) fp=np,fd=(nd+1)%4;
     83     for(int i=1;i<=c;move(np,nd,0),++i) {
     84         tmp[3][i]=np,tmp[7][i]=get_p(np,nd,3);
     85         tmpd[3][i]=nd,tmpd[7][i]=get_d(np,tmp[7][i],nd,3);
     86     }
     87     for(int i=0;i<4;i++)
     88         for(int j=1;j<=c;j++)
     89             modify(tmp[i][j],my_d(tmpd[i][j],i),tmp[(i+1)%4+4][j]);
     90     for(int i=4;i<8;i++)
     91         for(int j=1;j<=c;j++)
     92             modify(tmp[i][j],my_d(tmpd[i][j],(i+2)%4),tmp[(i-1)%4][j]);
     93 }
     94 void print() {
     95     Point xp=fp,yp;
     96     int xd=fd,yd;
     97     for(int i=1;i<=n;move(xp,xd,2),++i) {
     98         yp=xp;yd=xd;
     99         for(int j=1;j<=m;move(yp,yd,1),++j)
    100             printf("%d ",s[yp.x()][yp.y()]);
    101         printf("
    ");
    102     }
    103 }
    104 int main() {
    105     scanf("%d%d%d",&n,&m,&q);
    106     for(int i=0;i<=n+1;i++)
    107         for(int j=0;j<=m+1;j++) {
    108             if(i!=0&&i!=n+1&&j!=0&&j!=m+1)
    109                 scanf("%d",&s[i][j]);
    110             if(i!=0) a[i][j].p[0]=New(i-1,j);
    111             if(i!=n+1) a[i][j].p[2]=New(i+1,j);
    112             if(j!=0) a[i][j].p[3]=New(i,j-1);
    113             if(j!=m+1) a[i][j].p[1]=New(i,j+1);
    114         }
    115     fp=New(1,1);fd=0;
    116     for(int i=1,aa,bb,cc;i<=q;i++) {
    117         scanf("%d%d%d",&aa,&bb,&cc);
    118         change(aa,bb,cc);
    119     }
    120     print();
    121     return 0;
    122 }
    t3 Code

  • 相关阅读:
    yii2框架随笔27
    yii2框架随笔26
    yii2框架随笔25
    yii2框架随笔24
    yii2框架随笔23
    yii2框架随笔21
    yii2框架随笔20
    yii2框架随笔19
    yii2源码学习笔记(十五)
    yii2源码学习笔记(十四)
  • 原文地址:https://www.cnblogs.com/Gkeng/p/11354144.html
Copyright © 2011-2022 走看看