• ICPC2018焦作站 C. Supreme Command


    题意:

    有一个n*n棋盘,一开始上面有n个棋子,且每一行和每一列都恰好只有一个棋子

    给出m个操作

    所有棋子向上/下/左/右移动k格

    查询第i个棋子的位置

    查询现在有多少对棋子在同一个格子

    对于查询第i个棋子的位置:

    将二维棋盘的行列分离,单独计算

    以计算列为例

    每一列压缩为一行

    棋子一旦到达左右边界上,将永远处于同一列

    所有棋子左移,可以看成是棋盘的左边界右移

    所有棋子右移,可以看成是棋盘的右边界左移

    用l,r表示移动后的左右边界在第几列,即所有棋子都在长为r-l+1的区间里

    用一个变量δ表示出与实际在第几列的偏移量

    即[l+δ,r+δ]才是棋子实际在的区间

    偏移量的修改要根据棋子是否会到边界上分开计算

    查询的时候

    如果棋子的初始位置在l左边,说明棋子在左边界上

    如果棋子的初始位置在r右边,说明棋子在右边界上

    否则,棋子在区间里面

    计算行同理

    对于查询有多少个棋子在同一个格子:

    还是用棋子移动看作是棋盘边界移动

    这样棋子到同一个格子里只会发生在移动边界后的棋盘的四个角上

    如果棋子的初始位置既在左边界的左边,又在上边界的上边,那它就在左上角

    类推出其他三个角

    然后特判一行、一列、一个格子的情况

        #include<cstdio>
         
        #define N 300001
         
        int n;
         
        int a[N],b[N];
         
        long long C[N];
        int lu,ld,ru,rd;
         
        bool vis[N];
         
        void cal(int );
         
        struct node
        {
            int l,r,d;
            
            int pos[N],id[N]; 
            
            void initial()
            {
                l=1; 
                r=n;
                d=0;
            }
            
            void initial2()
            {
                cal(id[1]);
                cal(id[n]);
            }
            
            void add(int p,int i)
            {
                pos[i]=p;
                id[p]=i;
            }
            
            void movel(int k)
            {
                while(l<r && l+d-k<1) cal(id[++l]);    
                if(l+d-k>=1) d-=k;
                else d=1-l;
            }
            
            void mover(int k)
            {
                while(l<r && r+d+k>n) cal(id[--r]);
                if(r+d+k<=n) d+=k;
                else d=n-r;
            }
            
            int getpos(int x)
            {
                if(x<=l) return l+d;
                else if(x>=r) return r+d;
                else return x+d;
            }
            
        }lr,ud;
         
        void cal(int x)
        {
            if(vis[x]) return;
            if(lr.pos[x]<=lr.l && ud.pos[x]<=ud.l) 
            {
                vis[x]=true;
                lu++;
            }
            else if(lr.pos[x]<=lr.l && ud.pos[x]>=ud.r)
            {
                vis[x]=true;
                ld++;
            }
            else if(lr.pos[x]>=lr.r && ud.pos[x]<=ud.l)
            {
                vis[x]=true;
                ru++;
            }
            else if(lr.pos[x]>=lr.r && ud.pos[x]>=ud.r)
            {
                vis[x]=true;
                rd++;
            }
        }
         
        long long solve()
        {
            if(lr.l==lr.r && ud.l==ud.r) return C[lu+ld+ru+rd];
            if(lr.l==lr.r) return C[lu+ru]+C[ld+rd];
            if(ud.l==ud.r) return C[lu+ld]+C[ru+rd];
            return C[lu]+C[ru]+C[ld]+C[rd]; 
        }
         
        int main()
        {
            int T,m,x,y;
            char s[3];
            for(int i=1;i<N;++i) C[i]=1ll*(i-1)*i/2;
            scanf("%d",&T);
            while(T--)
            {
                scanf("%d%d",&n,&m);
                lr.initial();
                ud.initial();
                lu=ld=ru=rd=0;
                for(int i=1;i<=n;++i) vis[i]=0;
                for(int i=1;i<=n;++i)
                {
                    scanf("%d%d",&a[i],&b[i]);
                    lr.add(b[i],i);
                    ud.add(a[i],i);
                }
                lr.initial2();
                ud.initial2();
                while(m--)
                {
                    scanf("%s",s);
                    if(s[0]=='!') printf("%lld
    ",solve());
                    else
                    {
                        scanf("%d",&x);
                        if(s[0]=='L') lr.movel(x);
                        else if(s[0]=='R') lr.mover(x);
                        else if(s[0]=='U') ud.movel(x);
                        else if(s[0]=='D') ud.mover(x);
                        else printf("%d %d
    ",ud.getpos(a[x]),lr.getpos(b[x]));
                    }
                }
            }
        }
  • 相关阅读:
    Support for the experimental syntax 'classProperties' isn't currently enabled
    CssSyntaxError (2:1) Unknown word 1 | > 2 | var content = require("!!./index.css");
    vue-transition实现加入购物车效果及其他动画效果实现
    Array.reduce()方法
    Object.keys()返回对象自身可枚举属性组成的数组
    vue + mixin混入对象使用
    el-table + el-form实现可编辑表格字段验证
    深圳面试题
    深圳两年面试题
    JVM中的STW和CMS
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/14044826.html
Copyright © 2020-2023  润新知