BZOJ2647 : [Neerc2011]Journey_weixin_34204722的博客-程序员秘密

$|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;
}

  

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34204722/article/details/85975363

智能推荐

2020年土建方向-通用基础(施工员)多少分及格及土建方向-通用基础(施工员)新版试题_zbf123123的博客-程序员秘密

题库来源:安全生产模拟考试一点通公众号小程序2020年土建方向-通用基础(施工员)多少分及格及土建方向-通用基础(施工员)新版试题,包含土建方向-通用基础(施工员)多少分及格答案和解析及土建方向-通用基础(施工员)新版试题练习。由安全生产模拟考试一点通公众号结合国家土建方向-通用基础(施工员)考试最新大纲及土建方向-通用基础(施工员)考试真题汇总,有助于土建方向-通用基础(施工员)模拟试题考前练习。1、【判断题】挠度观测属于变形观测的一种。(√)2、【判断题】水准仪粗略整平的目的是使...

开源大数据周刊-第62期_aliyun32183的博客-程序员秘密

摘要: EMR资讯: EMR上线新地域:德国法兰克福资讯 AI 大师云集!CCAI 2017 中国人工智能大会盛大开幕7 月 22 - 23 日,在中国科学技术协会、中国科学院的指导下,由中国人工智能学会、阿里巴巴集团 & 蚂蚁金服主办,CSDN、中国科学院自动化研究所承办的 2017 中国人工智能大会(CCAI 2017)在杭州国际会议中心盛大召开。EMR资讯:EMR上线新地

vr全景制作方法,vr全景拍摄制作教程及总结_康1998的博客-程序员秘密

随着vr全景应用范围的扩大和普及,使得很多朋友关注到了这一技术。相较于图文视频等展现方式而言,vr全景像是展现形式的一个重大升级,不仅能够提供身临其境般的视角体验,更是能够融合各种功能和技术。这也给vr全景这一富媒体技术赋予了更多可能,针对不同的应用场景,结合不同技术和功能,就能够解决不同的行业痛点。很多感兴趣的朋友一定对vr全景制作方法还比较疑惑,今天这里就为大家带来了vr全景拍摄制作教程,相信大家看完全部的流程及总结之后就会全明白了。一、准备拍摄设备:相机、云台、三脚架、存储卡、相机电池、鱼眼镜头

Webpack配置vue组件的加载器(vue-loader)报错解决_蜗牛蜗牛大哥的博客-程序员秘密

首先介绍一下如何使用webpack来配置vue组件。第一步:在终端运行npm i vue-loader vue-template-compiler -D,安装处理vue组件的加载器,其中vue-template-compiler -D是vue-loader的内置依赖项。第二步:在项目的webpack.config.js文件中添加vue-loader的配置:①首先需要导入vue组件插件:const VueLoaderPlugin = require('vue-loader/lib/plugin.j

字符串案例__有光的博客-程序员秘密

案例1. 找到这个字符串中的每个字符串出现了多少次&amp;lt;script&amp;gt; var str = &quot;hello wod odd ott fbo nhyo&quot;; var key = &quot;o&quot;; // 开始的位置 var index = 0; // 要找的字符串 while ((index =str.index...

微信小程序组件化开发框架WePY_掘金-我是哪吒的博客-程序员秘密

wepy-CLI安装npm install -g wepy-cliwepy init standard my-projecthttps://github.com/Tencent/wepy特性:类Vue开发风格支持自定义组件开发支持引入NPM包支持Promise支持ES2015+特性,如Async Functions支持多种编译器,Less/Sass/Stylus/Post...

随便推点

【VSCode】【msys2】VS Code + msys2配置Windows下C/C++开发环境_msys2 vscode_伐尘的博客-程序员秘密

在.vscode目录下新建一个json文件:c_cpp_properties.json,注意includePath和compilerPath要指定到msys2安装目录下。还有个问题,就是VSCode显示#include 这一行有错,鼠标移上去显式找不到依赖文件stddef.h。把这个目录也添加到c_cpp_properties.json的includePath中,问题解决。原因是VSCode做代码分析的时候不知道gcc,选择了MSVC,添加配置文件把编译器改为gcc.愉快的coding!

running pre-commit hook: lint-staged_柠檬草。的博客-程序员秘密

running pre-commit hook: lint-staged前言错误日志分析解决办法前言vue项目中有些做了语法校验,遇到了git提交失败,根据错误提示,成功解决了问题。错误日志running pre-commit hook: lint-staged分析这句话的意思,大概是有一个钩子,提交前检查项目代码的规范,eslint的检查。提交失败的原因:项目中error过多,导致...

gamit 10.71首选rinex3_zzh_my的博客-程序员秘密

如题,目前cddis网站提供了既有rinex2、也有rinex3的数据,gamit 10.71的sh_get_rinex命令,如果从cddis网站下载,会首先下载两种格式的观测数据,也就是,例如brst0960.18d.ZBRST00FRA_R_20180960000_01D_30S_MO.crx.gz会把这2种格式的数据都下载到本地,然后解压,仅保留1个rinex3的o文件,其余的压缩文...

linux gcc c 的安装,C语言开发GCC命令报错linux应用之gcc环境的安装_钱建民的博客-程序员秘密

使用centos开发C语言程序,GCC编译时报错:bash:gcc:command not found解决方式,安装gcc环境我们知道,用yum install gcc可以安装gcc编译环境,关于 GCC 在 CentOS 下通过 yum 安装默认版本号,CentOS 5 是 4.1.2;CentOS 6 是 4.4.7;CentOS 7 是 4.8.3。很多时候在编译安装软件都需要高版本的 GC...

Mysql5.6.22-1安装及常见解决_fenqinqizheng的博客-程序员秘密

2.Mysql安装步骤:1)查看CentOS自带的mysql输入 rpm -qa | grep mysql2)将自带的mysql卸载rpm -e --nodeps mysql*3)上传Mysql到linux4)安装mysql的依赖(选做)yum -y install libaio.so.1 libgcc_s.so.1 libstdc++.so.6yum update libstdc+±4.4.7-4.el6.x86_645)解压Mysql到/usr/local/下的mysql目录(mys

vim 快速选中并复制粘贴替换一个单词_vim 复制一个单词_thinkKoa的博客-程序员秘密

1.光标移动到aaa的开头,按 v 按e 按y2.光标移动到bbb的开头,按 v 按e 按p也就说,快速选中一个单词,按v按e即可。