【CF375C】Circling Round Treasures
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);
}
【CF375C】Circling Round Treasures的更多相关文章
- CF 375C Circling Round Treasures [DP(spfa) 状压 射线法]
C - Circling Round Treasures 题意: 在一个$n*m$的地图上,有一些障碍,还有a个宝箱和b个炸弹.你从(sx,sy)出发,走四连通的格子.你需要走一条闭合的路径,可以自交 ...
- Circling Round Treasures CodeForces - 375C
C. Circling Round Treasures time limit per test 1 second memory limit per test 256 megabytes input s ...
- Codeforces 716A Crazy Computer 【模拟】 (Codeforces Round #372 (Div. 2))
A. Crazy Computer time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- Codeforces 716B Complete the Word【模拟】 (Codeforces Round #372 (Div. 2))
B. Complete the Word time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- 【CF1256】Codeforces Round #598 (Div. 3) 【思维+贪心+DP】
https://codeforces.com/contest/1256 A:Payment Without Change[思维] 题意:给你a个价值n的物品和b个价值1的物品,问是否存在取物方案使得价 ...
- 【JAVA】Math.Round()函数常见问题“四舍5入”
java.lang.Math.Round()使用时候,处理方式整理,方便以后查找 /** * 测试函数 2014-01-10 */ public class TestMath { pu ...
- 【Codeforces】Codeforces Round #551 (Div. 2)
Codeforces Round #551 (Div. 2) 算是放弃颓废决定好好打比赛好好刷题的开始吧 A. Serval and Bus 处理每个巴士最早到站且大于t的时间 #include &l ...
- Codeforces 375C Circling Round Treasures - 最短路 - 射线法 - 位运算
You have a map as a rectangle table. Each cell of the table is either an obstacle, or a treasure wit ...
- 【Codeforces】Codeforces Round #373 (Div. 2) -C
C. Efim and Strange Grade Efim just received his grade for the last test. He studies in a special sc ...
随机推荐
- 前端基础HTML
web的服务本质 浏览器发送请求>>>HTTP协议>>>服务端接受请求>>>服务端返回响应>>>服务端把HTML文件内容发给浏览 ...
- 设计模式C++实现
准备写一系列笔记用来记录学习设计模式的过程,同时写出自己对几种主要的设计模式的理解,以及编码实现,同时总结. 主要参考书籍就是 <Head First Design Patterns>这本 ...
- Linux命令之tar命令
[root@linux ~]# tar [-cxtzjvfpPN] 文件与目录 .... 参数: -c :建立一个压缩文件的参数指令(create 的意思): -x :解开一个压缩文件的参数指令! - ...
- KETTLE并行
1.转换的并行 转换的并行是改变复制的数量 上面的转换相当于下面的: 实际是把一个任务拆成三部分执行,相当于在一个数据库连接中做了三次查询,数据库连接的开销没有增加,但是有三个进程一起执行. 2.jo ...
- Python坑系列:可变对象与不可变对象
在之前的文章 http://www.cnblogs.com/bitpeng/p/4748148.html 中,大家看到了ret.append(path) 和ret.append(path[:])的巨大 ...
- ES6的新特性(21)——Proxy
Proxy 概述 Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程. Proxy 可以理解成,在目标对 ...
- 20181016-4 Alpha阶段第1周/共2周 Scrum立会报告+燃尽图 03
此作业链接地址见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2248 Scrum master:王硕 一.小组介绍 组长:王一可 组员 ...
- 王者荣耀交流协会-Alpha发布用户使用报告
用户数量:10人 姓名如下(包括化名):张小斌.王瑞瑞.蛋蛋.小美.晨曦.小丽.张利刚.小闫.小谢.小崔 寻找的用户多为王者荣耀交流协会成员的同学,对管理时间有着强烈的需求,也对PSP Daily软件 ...
- HDU 5428 The Factor 分解因式
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5428 The Factor Accepts: 101 Submissions: 811 Tim ...
- lilntcode-508-摆动排序
508-摆动排序 给你一个没有排序的数组,请将原数组就地重新排列满足如下性质 nums[0] <= nums[1] >= nums[2] <= nums[3].... 注意事项 请就 ...