zoukankan      html  css  js  c++  java
  • 【NOIP模拟赛】Drink 二维链表+模拟

    我觉得这道题的主旨应该是模拟,但是如果说他是二维链表的話也不為過。這道題的主體思路就是把原來旋轉點的O(n^2)變成了旋轉邊界的O(n)。怎麼旋轉邊界呢,就好像是把原來的那些點都於上下左右四個點連線,形成一個大網,我們要做的就是把要旋轉的正方形的四周的線都剪斷,然後轉一下再練上,實現的話就是二維點化一維點,所有的點自由化,然後每次找正方形從一個邊界點開始走進去走出來他的邊界,這裡只要注意記錄真實方向即可(只要能即時獲得即可)。

    思路固然重要,簡潔高效的代碼實現同樣重要,代碼實現同樣需要注入思考。

    #pragma GCC optimize("O3")
    #include <cstdio>
    #define shang(a) (p[(a)].t[p[(a)].f])
    #define xia(a) (p[(a)].t[(p[(a)].f+2)%4])
    #define zuo(a) (p[(a)].t[(p[(a)].f+1)%4])
    #define you(a) (p[(a)].t[(p[(a)].f+3)%4])
    inline void read(int &sum){
      register char ch=getchar();
      for(sum=0;ch<'0'||ch>'9';ch=getchar());
      for(;ch>='0'&&ch<='9';sum=(sum<<1)+(sum<<3)+ch-'0',ch=getchar());
    }
    const int N=2010;
    struct Point{
      int t[4],f,v;
    }p[N*N];
    int hash[N][N],sz;
    int n,m,q,tb[N],pg[N],zs[N],ys[N];
    inline int toward(int x,int y){
      for(int i=0;i<4;++i)
        if(p[x].t[i]==y)
          return i;
    }
    inline void get_fs(int x,int y){
      int j=toward(y,x);
      if(j==2)p[y].f=0;
      else if(j==0)p[y].f=2;
      else if(j==1)p[y].f=3;
      else p[y].f=1;
    }
    inline void get_fx(int x,int y){
      int j=toward(y,x);
      if(j==0)p[y].f=0;
      else if(j==2)p[y].f=2;
      else if(j==1)p[y].f=1;
      else p[y].f=3;
    }
    inline void get_fz(int x,int y){
      int j=toward(y,x);
      if(j==0)p[y].f=1;
      else if(j==2)p[y].f=3;
      else if(j==1)p[y].f=2;
      else p[y].f=0;
    }
    inline void get_fy(int x,int y){
      int j=toward(y,x);
      if(j==0)p[y].f=3;
      else if(j==2)p[y].f=1;
      else if(j==1)p[y].f=0;
      else p[y].f=2;
    }
    inline void print(){
      for(int i=1,now;i<=n;++i){
        now=hash[i][0];
        for(int j=1;j<=m;++j)
          get_fy(now,you(now)),now=you(now),printf("%d ",p[now].v);
        puts("");
      }
    }
    inline void read_pre(){
      read(n),read(m),read(q);
      for(int i=0;i<=n+1;++i)
        for(int j=0;j<=m+1;++j)
          hash[i][j]=++sz;
      for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
          read(p[hash[i][j]].v),
          p[hash[i][j]].t[0]=hash[i-1][j],
          p[hash[i][j]].t[2]=hash[i+1][j],
          p[hash[i][j]].t[1]=hash[i][j-1],
          p[hash[i][j]].t[3]=hash[i][j+1];
      for(int i=1;i<=n;++i)
        p[hash[i][0]].t[0]=hash[i-1][0],
        p[hash[i][0]].t[2]=hash[i+1][0],
        p[hash[i][0]].t[3]=hash[i][1],
        p[hash[i][m+1]].t[0]=hash[i-1][m+1],
        p[hash[i][m+1]].t[2]=hash[i+1][m+1],
        p[hash[i][m+1]].t[1]=hash[i][m];
      for(int i=1;i<=m;++i)
        p[hash[0][i]].t[1]=hash[0][i-1],
        p[hash[0][i]].t[3]=hash[0][i+1],
        p[hash[0][i]].t[2]=hash[1][i],
        p[hash[n+1][i]].t[1]=hash[n+1][i-1],
        p[hash[n+1][i]].t[3]=hash[n+1][i+1],
        p[hash[n+1][i]].t[0]=hash[n][i];
      p[hash[0][0]].t[3]=hash[0][1],
      p[hash[0][0]].t[2]=hash[1][0],
      p[hash[0][m+1]].t[1]=hash[0][m],
      p[hash[0][m+1]].t[2]=hash[1][m+1],
      p[hash[n+1][0]].t[0]=hash[n][0],
      p[hash[n+1][0]].t[3]=hash[n+1][1],
      p[hash[n+1][m+1]].t[0]=hash[n][m+1],
      p[hash[n+1][m+1]].t[1]=hash[n+1][m];
    }
    inline void work(){
      int x,y,l,now;
      while(q--){
        read(x),read(y),read(l);
        if(l==1)continue;
        int now=hash[x][0];
        for(int i=1;i<=y;++i)
          get_fy(now,you(now)),now=you(now);
        zs[1]=now;
        for(int i=2;i<=l;++i)
          get_fx(now,xia(now)),now=xia(now),zs[i]=now;
        for(int j=2;j<l;++j)
          get_fy(now,you(now)),now=you(now),pg[j]=now;
        get_fy(now,you(now)),now=you(now),ys[1]=now;
        for(int i=2;i<=l;++i)
          get_fs(now,shang(now)),now=shang(now),ys[i]=now;
        for(int j=2;j<l;++j)
          get_fz(now,zuo(now)),now=zuo(now),tb[j]=now;
        for(int i=2;i<l;++i)
          get_fs(tb[i],shang(tb[i])),xia(shang(tb[i]))=zs[i],
          get_fy(ys[i],you(ys[i])),zuo(you(ys[i]))=tb[i],
          get_fx(pg[i],xia(pg[i])),shang(xia(pg[i]))=ys[i],
          get_fz(zs[i],zuo(zs[i])),you(zuo(zs[i]))=pg[i];
        for(int i=2,temp;i<l;++i)
          temp=zuo(zs[i]),
          zuo(zs[i])=shang(tb[i]),
          shang(tb[i])=you(ys[i]),
          you(ys[i])=xia(pg[i]),
          xia(pg[i])=temp;
        get_fz(zs[1],zuo(zs[1])),you(zuo(zs[1]))=zs[l],
        get_fs(zs[1],shang(zs[1])),xia(shang(zs[1]))=zs[l],
        get_fy(ys[l],you(ys[l])),zuo(you(ys[l]))=zs[1],
        get_fs(ys[l],shang(ys[l])),xia(shang(ys[l]))=zs[1],
        get_fy(ys[1],you(ys[1])),zuo(you(ys[1]))=ys[l],
        get_fx(ys[1],xia(ys[1])),shang(xia(ys[1]))=ys[l],
        get_fz(zs[l],zuo(zs[l])),you(zuo(zs[l]))=ys[1],
        get_fx(zs[l],xia(zs[l])),shang(xia(zs[l]))=ys[1];
        int temp=shang(zs[1]);
        shang(zs[1])=you(ys[l]),
        you(ys[l])=xia(ys[1]),
        xia(ys[1])=zuo(zs[l]),
        zuo(zs[l])=temp;
        temp=zuo(zs[1]),
        zuo(zs[1])=shang(ys[l]),
        shang(ys[l])=you(ys[1]),
        you(ys[1])=xia(zs[l]),
        xia(zs[l])=temp;
      }
    }
    int main(){
      read_pre(),work(),print();
      return 0;
    }
  • 相关阅读:
    手游营销的10个靠谱方向
    创业三个月总结---记录这三个月的酸甜苦辣咸!!!
    创业三个月总结---记录这三个月的酸甜苦辣咸!!!
    Notepad++ 删除空白行的方法
    Notepad++ 删除空白行的方法
    几种常见容器比较和分析 hashmap, map, vector, list ...hash table
    hdu 3371
    hdu 1879
    hdu 1875
    hdu 1863
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7638177.html
Copyright © 2011-2022 走看看