BZOJ2647 : [Neerc2011]Journey
生活随笔
收集整理的這篇文章主要介紹了
BZOJ2647 : [Neerc2011]Journey
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
$|x|+|y|=\max(x+y,x-y,-x+y,-x-y)$,設$f[i][j]$表示在$(0,0)$,朝向方向$j$,執行第$i$條指令后的信息:
$cir$:是否陷入循環
$d$:朝向
$x,y$:坐標
$v_0$:$\max(x+y)$
$v_1$:$\max(x-y)$
$v_2$:$\max(-x+y)$
$v_3$:$\max(-x-y)$
然后記憶化搜索,當陷入循環時不再執行后面的指令。
用棧維護所有正在計算的狀態,若發現循環,則計算循環的$x$和$y$之和,若為$0$則是循環,否則會走到無限遠處。
時間復雜度$O(n^3)$。
?
#include<cstdio> #include<string> #include<iostream> #include<cstdlib> using namespace std; const int N=110,Base=100000000,MAXL=32; int n,i,j,a[N],q[N*4][2],in[N][4];string b[N][N];bool vis[N][4],cir[N][4]; inline int max(int a,int b){return a>b?a:b;} struct Num{int a[MAXL],len,fu;void init(){len=1,fu=a[1]=0;}Num(){init();}bool iszero(){return len==1&&!a[1];}Num operator+(const Num&b){Num c;c.len=max(len,b.len)+2;int i;for(i=1;i<=c.len;i++)c.a[i]=0;if(fu==b.fu){for(i=1;i<=len;i++)c.a[i]=a[i];for(i=1;i<=b.len;i++)c.a[i]+=b.a[i];for(i=1;i<=c.len;i++)if(c.a[i]>=Base)c.a[i+1]++,c.a[i]-=Base;while(c.len>1&&!c.a[c.len])c.len--;c.fu=fu;}else{bool flag=0;if(len==b.len){for(i=len;i;i--)if(a[i]!=b.a[i]){if(a[i]>b.a[i])flag=1;break;}}else{if(len>b.len)flag=1;}if(flag){for(i=1;i<=len;i++)c.a[i]=a[i];for(i=1;i<=b.len;i++)c.a[i]-=b.a[i];for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;while(c.len>1&&!c.a[c.len])c.len--;c.fu=fu;}else{for(i=1;i<=b.len;i++)c.a[i]=b.a[i];for(i=1;i<=len;i++)c.a[i]-=a[i];for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;while(c.len>1&&!c.a[c.len])c.len--;c.fu=b.fu;}}if(c.iszero())c.init();return c;}void operator+=(const Num&b){*this=*this+b;}Num operator-(const Num&b){Num c;c.len=max(len,b.len)+2;int i;for(i=1;i<=c.len;i++)c.a[i]=0;if(fu!=b.fu){for(i=1;i<=len;i++)c.a[i]=a[i];for(i=1;i<=b.len;i++)c.a[i]+=b.a[i];for(i=1;i<=c.len;i++)if(c.a[i]>=Base)c.a[i+1]++,c.a[i]-=Base;while(c.len>1&&!c.a[c.len])c.len--;c.fu=fu;}else{bool flag=0;if(len==b.len){for(i=len;i;i--)if(a[i]!=b.a[i]){if(a[i]>b.a[i])flag=1;break;}}else{if(len>b.len)flag=1;}if(flag){for(i=1;i<=len;i++)c.a[i]=a[i];for(i=1;i<=b.len;i++)c.a[i]-=b.a[i];for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;while(c.len>1&&!c.a[c.len])c.len--;c.fu=fu;}else{for(i=1;i<=b.len;i++)c.a[i]=b.a[i];for(i=1;i<=len;i++)c.a[i]-=a[i];for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;while(c.len>1&&!c.a[c.len])c.len--;c.fu=b.fu^1;}}if(c.iszero())c.init();return c;}void operator-=(const Num&b){*this=*this-b;}bool operator<(const Num&b){if(fu!=b.fu)return fu;if(fu){if(len!=b.len)return len>b.len;for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]>b.a[i];}else{if(len!=b.len)return len<b.len;for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]<b.a[i];}return 0;}void write(){if(fu)putchar('-');printf("%d",a[len]);for(int i=len-1;i;i--)printf("%08d",a[i]);}void set(int x){fu=0;if(x<0)x=-x,fu=1;len=1;a[1]=x;} }zero,one,x,y; inline void up(Num&a,const Num&b){if(a<b)a=b;} struct E{int d;Num x,y,v0,v1,v2,v3;void left(){d=(d+1)&3;}void right(){d=(d+3)&3;}void init(int _d){d=_d;x.set(0);y.set(0);v0.set(0);v1.set(0);v2.set(0);v3.set(0);}void go(){if(d==0)x+=one;if(d==1)y+=one;if(d==2)x-=one;if(d==3)y-=one;up(v0,x+y);up(v1,x-y);up(v2,y-x);up(v3,zero-x-y);}void merge(const E&b){d=b.d;up(v0,x+y+b.v0);up(v1,x-y+b.v1);up(v2,y-x+b.v2);up(v3,zero-x-y+b.v3);x+=b.x;y+=b.y;}void write(){up(v0,v1);up(v0,v2);up(v0,v3);v0.write();} }f[N][4]; inline int cal(const string&s){int t=0;for(int i=1;i<s.size();i++)t=t*10+s[i]-'0';return t; } inline void check(int l,int r){for(x.set(0),y.set(0);l<=r;l++)x+=f[q[l][0]][q[l][1]].x,y+=f[q[l][0]][q[l][1]].y;if(x.iszero()&&y.iszero())return;puts("Infinity");exit(0); } void cal(int x,int y,int d){if(vis[x][y])return;vis[x][y]=1;q[in[x][y]=d][0]=x;q[d][1]=y;f[x][y].init(y);for(int i=0;i<a[x];i++){if(b[x][i]=="GO")f[x][y].go();else if(b[x][i]=="LEFT")f[x][y].left();else if(b[x][i]=="RIGHT")f[x][y].right();else{int A=cal(b[x][i]),B=f[x][y].d;if(in[A][B]){check(in[A][B],d);cir[x][y]=1;}else{cal(A,B,d+1);f[x][y].merge(f[A][B]);if(cir[A][B])cir[x][y]=1;}if(cir[x][y])break;}}in[x][y]=0; } int main(){zero.set(0);one.set(1);cin>>n;for(i=1;i<=n;i++){cin>>a[i];for(j=0;j<a[i];j++)cin>>b[i][j];}cal(1,0,1);f[1][0].write();return 0; }
轉載于:https://www.cnblogs.com/clrs97/p/8537219.html
總結
以上是生活随笔為你收集整理的BZOJ2647 : [Neerc2011]Journey的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: x86 linux 裁剪过程中能正常跑起
- 下一篇: 第013课_代码重定位