NOIP模拟赛Drink 二维链表+模拟

Posted TS_Hugh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

 

以上是关于NOIP模拟赛Drink 二维链表+模拟的主要内容,如果未能解决你的问题,请参考以下文章

luogu2038noip2014无线网络发射器选址 [模拟][二维前缀和]

YYH的营救计划(NOIP模拟赛Round 6)

NOIP2014-10-30模拟赛

[计蒜客NOIP模拟赛]2017.7.28Day1回顾反思总结

P1058 [NOIP2008 普及组] 立体图(模拟)

P1058 [NOIP2008 普及组] 立体图(模拟)