Portal --> CF375C

Solution

  一个有趣的事情:题目中有很大的篇幅在介绍如何判断一个位置在不在所围的多边形中

  那么。。给了方法当然就是要用啊

​  首先是不能包含\('B'\),处理方式很简单直接把他当成一个值为\(-inf\)的宝藏即可,这样所有的object就全部可以看成一类了,不需要再额外考虑

  注意到object的总数很少,考虑状压,记\(vis[x][y][st]\)表示当前在\((x,y)\)这个点,射线与路径的交点数量为奇数的object的状态为\(st\),这种局面是否可行,然后对应的开一个\(step[x][y][st]\)表示达到这种局面所需要的最少步数,这个时候。。最短路既视感?

​  反正\(n\)和\(m\)也不大,所以我们可以考虑跑一个最短路,最后枚举一下\(st\),然后用\((x,y)\)为起点位置的状态去更新一下答案就好了

  现在的问题是,如何计算一步移动对object的射线的影响

​  注意到这个射线其实随便选就好了。。所以方便起见,我们可以钦定每个点只看往其左上方延伸的、角度很小很小很小的一条射线就好了(也可以是别的方向啦随意随意,不过角度很小这个比较重要),角度小这个有一个好处就是,因为角度很小所以只有当纵坐标改变的时候才有可能产生交点,然后其他的情况判断就十分简单了

  

  mark:特殊值什么的是个好东西

  mark:没有思路的时候。。可以尝试从描述里面找提示。。?

  

​  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=25,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1},ST=1<<8;
const int inf=1e4;
struct Rec{
int x,y,val;
}a[20];
struct Data{
int x,y,st;
Data(){}
Data(int x1,int y1,int st1){x=x1; y=y1; st=st1;}
};
queue<Data> q;
int vis[N][N][ST],step[N][N][ST],inq[N][N][ST];
char mp[N][N];
int n,m,t,stx,sty,cnt,ans;
int St(int x){return 1<<x-1;}
bool in(int st,int x){return st>>(x-1)&1;}
bool ok(int x,int y){
if (x<1||y<1||x>n||y>m) return false;
return mp[x][y]=='.'||mp[x][y]=='S';
}
bool check(int x,int y,int nwx,int nwy,int id){
if (x==nwx) return false;
if (x==a[id].x&&y<a[id].y) return nwx<x;
if (nwx==a[id].x&&nwy<a[id].y) return x<nwx;
return false;
}
void bfs(){
Data v,u;
int x,y,st,xx,yy,nw;
while (!q.empty()) q.pop();
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
for (int k=0;k<(1<<cnt);++k)
step[i][j][k]=inf,inq[i][j][k]=false;
q.push(Data(stx,sty,0)); inq[stx][sty][0]=true;
step[stx][sty][0]=0;
while (!q.empty()){
x=q.front().x; y=q.front().y; st=q.front().st; q.pop();
vis[x][y][st]=true;
for (int i=0;i<4;++i){
xx=x+dx[i]; yy=y+dy[i];
if (!ok(xx,yy)) continue;
nw=st;
for (int j=1;j<=cnt;++j)
if (check(x,y,xx,yy,j))
nw^=St(j);
if (step[xx][yy][nw]>step[x][y][st]+1){
step[xx][yy][nw]=step[x][y][st]+1;
if (!inq[xx][yy][nw])
q.push(Data(xx,yy,nw)),inq[xx][yy][nw]=true;
}
}
inq[x][y][st]=false;
}
}
void get_ans(){
int tmp;
for (int st=0;st<(1<<cnt);++st){
if (!vis[stx][sty][st]) continue;
tmp=0;
for (int i=1;i<=cnt;++i)
if (in(st,i))
tmp+=a[i].val;
ans=max(ans,tmp-step[stx][sty][st]);
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d%d\n",&n,&m);
t=0; cnt=0;
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
scanf("%c",&mp[i][j]);
if ('0'<=mp[i][j]&&mp[i][j]<='9'){
a[mp[i][j]-'0'].x=i,a[mp[i][j]-'0'].y=j;
t=max(t,mp[i][j]-'0');
++cnt;
}
else if (mp[i][j]=='S')
stx=i,sty=j;
}
scanf("\n");
}
for (int i=1;i<=t;++i) scanf("%d",&a[i].val);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
if (mp[i][j]=='B')
a[++cnt].x=i,a[cnt].y=j,a[cnt].val=-inf;
bfs();
get_ans();
printf("%d\n",ans);
}

最新文章

  1. Linux系统编程之IO_缓冲和非缓冲
  2. 小程序实现sql插入语句转换成Laravel迁移语句
  3. 嵌入式系统上实现GPS全球定位功能
  4. Mac 下安装ruby,以及CocoaPods安装以及使用网摘
  5. node.js使用汇总贴
  6. oracle连接的三个配置文件(转)
  7. css 默认样式
  8. Tomcat 配置 Probe 监控
  9. zip命令的用法
  10. JRE System Library [JavaSE-1.7](unbound)
  11. idea Empty git --version output:解决
  12. 深入探究Lua的GC算法(上)-《Lua设计与实现》
  13. vue文件在编辑器Sublime Text3中高亮
  14. cocos2dx游戏--欢欢英雄传说--添加游戏背景
  15. c++第十九天
  16. A*搜索 概念
  17. XE7 &amp; FMX 那些年我们一起上过的控件:StringGrid 之(1) 自定义标题样式
  18. scrapy 抓取数据被禁止的解决方法
  19. CodeForces 663A Rebus
  20. C 时间函数总结

热门文章

  1. 如何运用 Powershell 修改Office365和AD账户
  2. Python Web部署方式全汇总
  3. git实验
  4. ES6的新特性(4)——字符串的扩展
  5. USACO 1.3.3 Calf Flac(Manacher算法)
  6. Table Tennis Game 2(找规律)
  7. 基于NABCD评论作品,及改进建议
  8. “Hello World!”团队第十三次会议
  9. Win10系统自带输入法的人机交互设计
  10. APUE(unix环境高级编程)第三版---first day---部署书中实例的运行环境(apue.h)