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无线网络发射器选址 [模拟][二维前缀和]