蓝桥杯算法训练——lift and throw
来源:互联网 发布:手机限制软件联网 编辑:程序博客网 时间:2024/06/03 11:17
#include <iostream>#include <cmath>#include <cstring>using namespace std;#define M 50struct People{ int pos; bool lifted;//正在被举着 bool lifting;//正在举着别人 int lift;//举着的是谁 int maxmove;//最大移动距离 int maxthrow;//最大抛距离 bool hasmoved;//是否移动过 bool haslifted;//是否举过别人 //没有必要加上是否抛过别人的标记,因为只能举起别人一次}p[3];bool Pos[M];//数轴,作为标记是否某位置上有人 bool visit[10];//排序标记,有三个人且每个人有移动、举起、抛出三种状态,共有9种操作 int Max=0;//记录最大位置 void dfs(int k,int step){int n = k / 3; //当前执行操作的人 int m = k % 3; //当前执行的动作//moveif(m==0){if(p[n].lifted || p[n].lifting || p[n].hasmoved) return;int i=1;if(step == 9) i=p[n].maxmove;//最后一步,则直接向前移动最大距离/*如果不是最后一步,那么他也不必从他能移动的最靠后的距离开始搜索 他只需要从 他的位置之前的 有人的位置 的前一个位置 开始搜索即可 如果他后面没人,那么他走的距离只需要从1开始搜索,不需要往后走,只需要往前走*/ else{for(int j=1;j<p[n].pos;j++)//从第一个位置到p[i]的当前位置遍历 {if(Pos[j])//找p[i]前面有人的位置,以此来判断移动距离 {int l = -(p[n].pos-j-1);//l为移动位置的 后一个位置 i= l<i?l:i;}} i = i > -p[n].maxmove ? i : -p[n].maxmove;//移动的距离不可以大于p[i]的最大移动距离}//找出i---即最大移动多少步for(;i <= p[n].maxmove; i++) {if(Pos[p[n].pos+i-1] || Pos[p[n].pos+i+1] || i==p[n].maxmove) //移动到的位置 的 前后有人,才可以进行举起抛出,才有意义 {if(p[n].pos+i >0 && !Pos[p[n].pos+i])//不可以移动到数轴外,且移动的位置必须为空 {if(!i)continue;//i=0,表示不移动,进入下一个for循环 Pos[p[n].pos]=false;//当前位置置零 p[n].pos += i;//move i步 Pos[p[n].pos]=true;//move后的位置 置为1 p[n].hasmoved=true;//标记 Max= p[n].pos>Max ? p[n].pos : Max;//记录最大位置//向下一步 深搜for(int j=0;j<9;j++){if(!visit[j]){visit[j]=true;dfs(j,step+1); //向下一步 深搜visit[j]=false;//回溯 }}//回溯 Pos[p[n].pos]=false;p[n].pos -= i;Pos[p[n].pos]=true; p[n].hasmoved=false; }}}}//liftelse if(m==1){if(p[n].lifted || p[n].lifting || p[n].haslifted) return;for(int i=0;i<3;i++)//找旁边的人,初始判断条件为两者距离为1 {if(abs(p[i].pos-p[n].pos) == 1){if(p[i].lifted) continue;//如果这个人正被举着,则不能重复举起//否者,标记相关信息 p[n].haslifted=true;p[n].lifting=true;p[n].lift=i;p[i].lifted=true;int temp=p[i].pos; //临时中间变量,以便回溯 Pos[p[i].pos]=false;//i被举起,则位置p[i].pos为空 p[i].pos=p[n].pos;//p[i]的位置即为p[n]的位置//如果被举起的人i正在举着别人,则i举着的那个人的位置也要改变 if(p[i].lifting) {int j=p[i].lift;// j就是被i举着的人p[j].pos=p[i].pos; }//继续搜索for(int j=0;j<9;j++) {if(!visit[j]){visit[j]=true;dfs(j,step+1);//向下一步深搜 visit[j]=false;}}//回溯(将一切标记过的或者改动过的还原) p[n].haslifted=false;p[n].lifting=false;p[n].lift= -1;p[i].lifted=false;p[i].pos=temp;//临时变量的作用即为 记下p[i]的原始位置,便于i还原 Pos[p[i].pos]=true;//p[i]举着的人j也要记得还原为 :p[j]所被p[i]举着的位置 if(p[i].lifting) {int j=p[i].lift;// j就是被i举着的人p[j].pos=p[i].pos; }}}}//throwelse{if(!p[n].lifting || p[n].lifted) return;//如果这个人并没有举着别人,这或个人正被举着,则退出 int i=1;if(step == 9) i=p[n].maxthrow;//最后一步,直接向前抛出最大距离 else{for(int j=1;j<p[n].pos;j++)//从第一个位置到p[i]的当前位置遍历 {if(Pos[j])//找p[i]前面有人的位置,以此来判断抛出距离 {int l=-(p[n].pos-j-1);//l为抛出位置的 后一个位置 i=l<i?l:i;}} i= i> -p[n].maxthrow? i : -p[n].maxthrow;//抛出的距离不可以大于p[i]的最大抛出距离}//找出i---即最大抛出多少步for( ;i <= p[n].maxthrow; i++) {if(Pos[p[n].pos+i-1] || Pos[p[n].pos+i+1] || i == p[n].maxthrow) //抛出到的位置 的 前后为空,才有意义 {if(p[n].pos+i>0 && !Pos[p[n].pos+i])//不可以抛出到数轴外,且抛出所到的位置必须为空 {int j=p[n].lift;//j为要被抛出的(即n举着的)人 p[j].pos += i;//j 被throw i步 Pos[p[j].pos]=true;//throw后的位置 置为1 p[n].lifting=false;//标记p[n].lift = -1;p[j].lifted=false;//抛出后即为不再是被举起状态 Max= p[j].pos>Max ? p[j].pos : Max;//记录最大位置//若被抛出的j的头顶上还举着人 if(p[j].lifting){int k=p[j].lift;//k为被j举着的人 p[k].pos=p[j].pos;//k的位置与j位置同步 }//向下一步 深搜for(int q=0;q<9;q++){if(q == k) continue;//if(!visit[q]){visit[q]=true;dfs(q,step+1); //向下一步 深搜visit[q]=false;//回溯 }}//回溯 Pos[p[j].pos]=false;p[j].pos -= i; p[j].lifted=true; p[n].lift=j;p[n].lifting=true;if(p[j].lifting){int k=p[j].lift;p[k].pos=p[j].pos;} }}}} }int main(){ memset(Pos, false, sizeof(Pos)); memset(visit, false, sizeof(visit)); //输入 for(int i = 0; i < 3; i++) { cin >> p[i].pos >> p[i].maxmove >> p[i].maxthrow; p[i].lifted = p[i].lifting = p[i].hasmoved = p[i].haslifted = false; p[i].lift = -1; Pos[p[i].pos] = true; } //深搜 for(int i = 0; i < 9; i++) { //一个合法的第一步,不可能是抛。必须先移动或者举起别人 if((i % 3) != 2) { visit[i] = true; dfs(i, 1); visit[i] = false;//回溯 } } //结果 cout << Max << endl; return 0;}
0 0
- 蓝桥杯算法训练——lift and throw
- 蓝桥杯 算法训练 Lift and Throw
- 蓝桥杯 算法训练 Lift and Throw
- 蓝桥杯 算法训练 Lift and Throw
- 蓝桥杯 算法训练 Lift and Throw
- 算法训练 Lift and Throw (DFS && 位运算)
- ALGO137——Lift and Throw
- 算法训练_Lift and Throw
- 蓝桥杯练习系统 Lift and throw
- lift and throw
- Lift and Throw 只是运行出结果,分数却比较低
- lift and throw(from蓝桥)(深度优先搜索)
- 蓝桥杯——算法训练 报时助手
- 蓝桥杯——算法训练 分解质因数
- 蓝桥杯——算法训练 P1103
- 蓝桥杯—— 算法训练 图形显示
- 蓝桥杯—— 算法训练 Anagrams问题
- 蓝桥杯—— 算法训练 完数
- iOS中的相等== isEqual isEqualToString
- Dalvik字节码
- 【面试题】剑指offer 13
- JavaScript对象宽度高度属性整理
- sdutacm-超排序
- 蓝桥杯算法训练——lift and throw
- [生存志] 第134节 兵锋十万踏匈奴
- ios指纹识别
- super的使用
- ScrollView中嵌套recycleView 出现的不显示,显示不全,终极解决方案
- ORA-01102 cannot mount database in EXCLUSIVE mode
- ZigBee DataRequest Poll机制解析
- PostgreSQL基本操作-Linux
- Linux下模拟多线程的并发shell脚本写法