1560 扔人游戏
来源:互联网 发布:手机淘宝领天猫积分 编辑:程序博客网 时间:2024/06/05 09:50
1560 扔人游戏
Description
有一条射线端点在左边,把它分成单位长度的线段,每条线段的端点为一个位置。这些位置从1开始编号(端点开始),然后是2,3等等。位置之间的距离等于位置编号之差的绝对值。
小A,小B,小C分别站在射线的三个不同的位置上。他们想要到达编号尽可能大的位置上。一开始,他们三个人的位置是不一样的。
每个人可以执行以下每个操作最多一次:
- 移动一定的距离。
- 抓住另一个人并举到头顶。
- 把抓在手中的人扔出一定的距离。
每个人都有一定的移动范围。并且只能移动到一个没有人站的位置上。
如果一个人(p1)和另一个人(p2)的距离为1,并且p2没有被人抓住,p1也没有抓住别人,那么p1可以抓住p2.当p1抓住p2后,p2要来到p1的位置,而原来p2的位置变成空,即没有人站着。p1抓住p2后,p2不可以进行任何动作,p1不可以移动,但可以扔人。
每个人扔人时都有一定的范围。指的是他能把头顶上的人扔出的最远距离。当他的头顶有人时,他可以扔人。扔人时只能把人扔到一个没有人站着的位置上。
有一种特殊情况,当一个人抓住另一个人,而此时后者手中也抓住一个人。这时三个人就会形成一列站在同一个位置上。举个例子。小B举起小C,然后小A举起小B。这种情况下,小B和小C不能做任何动作。而小A可以把小B小C一起扔出。扔出后小B和小C会一起落在同一个位置,状态还是小B举着小C。
小A,小B,小C行动的顺序是任意的。但是每次只能有一个人行动。
现在我们的任务是,计算小A,小B,小C可以到达的位置中最大编号是多少。如果小A,小B,小C最后达到位置是pa,pb,pc的话,也就是使得max(pa,pb,pc)要最大。
样例解释:
一开始小A站在9,小B站在4,小C站在2
先让小A移动到6
然后小C移动到5并抓住小B
小A抓住C并扔到9
小C把小B扔到12
小B移动到15
Input
单组测试数据
第一行包含三个整数,分别表示小A的位置,移动的范围,和扔人的范围。
第二,第三行格式和第一行相同,分别表示小B和小C的对应数据。
三个初始位置是不同的,所有的输入的整数X都在[1,10](含)。
Output
共一行,三个人中可以达到最大位置的编号。
Input示例
9 3 3
4 3 1
2 3 3
Output示例
15
Solution
这是一道神奇的暴力题,讲道理我这个蒟蒻竟然一开始没看出来,幸亏看了题目标签和神犇代码(为什么有是看代码因为我太弱啦),这道题目我使用了(其实是神犇)用了位运算,简直是精妙无比,代码中用四位二进制数来表示状态,先来解释一发(0011)为初始状态:
0(没有意义,不过为了好看)
0(不可以抛出,因为手上还没有举起,若为1,则可抛出)
1(没有举起人,若为0,则已经进行举起)
1(没有移动过,若为1,则已经进行移动)
看懂这段二进制描述,就可以无压力的看接下来的代码
(其中flag[]表示当前这个[]可不可以操作,因为如果举起人或者被人家举起来,就不能操作了)
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int x[4],t[4],p[4],peo[4],w[4],flag[4]={3,3,3,3},ans;int Abs(int x){ if (x<0) return -x; return x;}int check(int nw){ for (int i=1;i<=3;i++) if (Abs(x[i]-nw)==1) return 1; return 0;}void dfs(){ for (int i=1;i<=3;i++) ans=max(ans,x[i]); for (int i=1;i<=3;i++){ if (w[i]) continue; if (flag[i]&1 && !(flag[i]&4)){ for (int j=1;j<=p[i];j++){ x[i]+=j;flag[i]^=1; if (check(x[i]) || j==p[i]) dfs(); x[i]-=j; x[i]-=j; if (check(x[i]) || j==p[i]) dfs(); x[i]+=j;flag[i]^=1; } } if (flag[i]&2) for (int j=1;j<=3;j++) if (i!=j && !w[j] && t[i]>0) if (Abs(x[i]-x[j])==1){ int pos=0; w[j]=1;flag[i]^=2;flag[i]^=4;peo[i]=j;pos=x[j];x[j]=-j; dfs(); flag[i]^=2;flag[i]^=4;x[j]=pos;w[j]=0; } if (flag[i]&4) for (int j=1;j<=t[i];j++){ int pos=0; w[peo[i]]=0;flag[i]^=4;pos=x[peo[i]];x[peo[i]]=x[i]+j; if (check(x[peo[i]]) || j==t[i]) dfs(); x[peo[i]]-=j; x[peo[i]]-=j; if (check(x[peo[i]]) || j==t[i]) dfs(); w[peo[i]]=1;flag[i]^=4;x[peo[i]]=pos; } }}int main(){ for (int i=1;i<=3;i++) scanf("%d%d%d",&x[i],&p[i],&t[i]); dfs(); printf("%d\n",ans);}
阅读全文
0 0
- 1560 扔人游戏
- 51Nod-1560-扔人游戏
- [unity&独立游戏]多人游戏插件
- 扔飞镖游戏
- 游戏玩人
- 算法-踢人游戏
- 炸弹人 游戏
- 游戏
- 游戏
- 游戏
- 游戏
- 游戏...
- 游戏
- 游戏
- 游戏
- 游戏
- 游戏
- #游戏
- 克拉美罗下界 CRLB的计算
- Leetcode 122 Best Time to Buy and Sell Stock II
- linux下动态库(共享库)
- 使用foreach操作数组
- HDU 5977 树的分治+子集枚举
- 1560 扔人游戏
- Leetcode 349 Intersection of Two Arrays
- 查看linux中的TCP连接数
- 地图集web项目_技术学习(一)_前后端数据传输(ajax)
- Leetcode 350 Intersection of Two Arrays II
- Matlab学习笔记(9)——textread函数
- C++中for循环的5种语法
- codevs 1021 玛丽卡 图论:最短路
- Mac 安装JDK 配置环境变量