标签:更新 位置 max math 不能 ring range 说明 情况下
要注意的有以下几点:1. 从数据规模可知,最大距离小于50,那么坐标轴的数组大小开50就足够了;2. 9次操作的第一步应当是移动或举起,而不是抛出;3. 若当前是最后一步操作,那么直接移动至可移动的最大距离 或 抛出至可抛出的最大距离;4. 已移动过、正举着人、正被举着的人不能移动;已举起过、正举着人、正被举起的人不能举起别人;未举着人、正被举起的人不能进行抛出操作;5. 移动和抛出的目标位置只需考虑两种情况:其他人旁边的位置、可移动/可抛出的最远的位置;6. 若当前操作是移动或抛出,若当前执行操作的人后面有人,那么从此人(坐标轴最左边的人)右边第一个位置开始遍历;若后面无人,那么从自己右边第一个位置开始遍历;7. 目标位置必须确保 还在坐标轴上(即下标>0)且 目标位置无人;
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <algorithm> 8 #define INF 0x3f3f3f3f 9 #define zero 1e-7 10 11 using namespace std; 12 typedef long long ll; 13 const ll mod=50000; 14 const ll max_n=2e5+7; 15 16 struct node {//0表示否,1表示是,-1表示没举着任何人 17 int pos;//当前所在位置 18 int maxMove;//可移动的最大距离 19 int maxThrow; //可扔出的最大距离 20 bool beup;//是否被举着 21 int upwho;//是否举着,举着谁 22 bool hasmove;//是否曾移动过 23 bool hasup;//是否曾举过(扔过) 24 }p[3];//三个人 25 26 int maxd=0; 27 bool axis[50]={0};//标记数轴上是否有人,0表示无 28 bool ops[10]={0};//9个操作全排列 29 30 void dfs(int k, int step) { 31 int n=k/3;//当前执行操作的人 32 int m=k%3;//当前执行的操作 33 if(!m) {//移动 34 if(p[n].beup || p[n].hasmove || p[n].upwho!=-1) return;//被举着、移动过、举着人的人不能移动 35 int l=1; 36 if(step==9) l=p[n].maxMove;//若当前是最后一步操作,则直接移动最大距离即可 37 else { 38 for(int i=1; i<p[n].pos; i++) { 39 if(axis[p[i].pos]) {//找到坐标轴上第一个人的位置 40 l=-(p[n].pos-i-1); 41 break; 42 } 43 } 44 l=max(l, -p[n].maxMove);//移动距离不能超过maxMove 45 } 46 for(int i=l; i<=p[n].maxMove; i++) { 47 if(axis[p[n].pos+i-1] || axis[p[n].pos+i+1] || i==p[n].maxMove) {//目标位置应是其他人的旁边的位置或者能移动的最大距离 48 if(p[n].pos+i>0 && !axis[p[n].pos+i]) {//确保在坐标轴范围内 且 目标位置无人 49 if(!i) continue;//目标位置不能是自己当前所在位置 50 //以下,修改移动后需要更新的值 51 axis[p[n].pos]=false; 52 p[n].pos+=i; 53 axis[p[n].pos]=true; 54 p[n].hasmove=true; 55 maxd=max(p[n].pos, maxd); 56 57 //继续下一步搜索 58 for(int j=0; j<9; j++) { 59 if(!ops[j]) { 60 ops[j]=true; 61 dfs(j, step+1); 62 ops[j]=false; 63 } 64 } 65 //回溯 66 p[n].hasmove=false; 67 axis[p[n].pos]=false; 68 p[n].pos-=i; 69 axis[p[n].pos]=true; 70 } 71 } 72 } 73 } 74 if(m==1) {//举起 75 if(p[n].upwho!=-1 || p[n].beup || p[n].hasup) return;//未举着人、被举着、举过人的人不能举起别人 76 for(int i=0; i<3; i++) {//枚举每个人的位置 77 if(abs(p[i].pos-p[n].pos)==1) {//如果刚好有人在这个人旁边 78 if(p[i].beup) continue;//i不能重复被举起 79 80 p[n].hasup=true; 81 p[n].upwho=i; 82 p[i].beup=true; 83 int temp=p[i].pos;//记录i的位置,以便回溯 84 axis[p[i].pos]=false; 85 p[i].pos=p[n].pos; 86 if(p[i].upwho!=-1) //若i举着人 87 p[p[i].upwho].pos=p[i].pos; 88 89 //继续下一步搜索 90 for(int j=0; j<9; j++) { 91 if(!ops[j]) { 92 ops[j]=true; 93 dfs(j, step+1); 94 ops[j]=false; 95 } 96 } 97 //回溯 98 p[n].hasup=false; 99 p[n].upwho=-1; 100 p[i].beup=false; 101 p[i].pos=temp; 102 axis[p[i].pos]=true; 103 if(p[i].upwho!=-1) 104 p[p[i].upwho].pos=p[i].pos; 105 } 106 } 107 } 108 if(m==2) {//抛出 109 if(p[n].upwho==-1 || p[n].beup) return;//若没有举起别人或正被举起,则不可抛出 110 int l=1; 111 if(step==9) l=p[n].maxThrow;//若当前为最后一步操作,则直接抛出到最远距离 112 else { 113 for(int i=1; i<p[n].pos; i++) { 114 if(axis[i]) { 115 l=-(p[n].pos-i-1); 116 break; 117 } 118 } 119 l=max(l, -p[n].maxThrow);//扔出距离不能超过maxThrow 120 } 121 for(int i=l; i<=p[n].maxThrow; i++) { 122 if(p[n].pos+i>0 && !axis[p[n].pos+i]) {//确保目标位置还在坐标轴范围内 且 目标位置无人 123 if(axis[p[n].pos+i-1] || axis[p[n].pos+i+1] || i==p[n].maxThrow) {//目标位置应是其他人旁边或可扔出的最大距离 124 125 int temp=p[n].upwho;//记录举着谁以便回溯 126 p[temp].pos+=i; 127 p[temp].beup=false; 128 p[n].upwho=-1; 129 p[n].hasup=true; 130 axis[p[temp].pos]=true; 131 maxd=max(maxd, p[temp].pos); 132 if(p[temp].upwho!=-1) 133 p[p[temp].upwho].pos=p[temp].pos; 134 135 //继续下一步搜索 136 for(int j=0; j<9; j++) { 137 if(!ops[j]) { 138 ops[j]=true; 139 dfs(j, step+1); 140 ops[j]=false; 141 } 142 } 143 //回溯 144 axis[p[temp].pos]=false; 145 p[temp].pos=p[n].pos; 146 p[temp].beup=true; 147 p[n].upwho=temp; 148 if(p[temp].upwho!=-1) 149 p[p[temp].upwho].pos=p[temp].pos; 150 } 151 } 152 } 153 } 154 } 155 156 int main() { 157 for(int i=0; i<3; i++) { 158 cin>>p[i].pos>>p[i].maxMove>>p[i].maxThrow; 159 p[i].beup=false; 160 p[i].upwho=-1; 161 p[i].hasmove=false; 162 p[i].hasup=false; 163 axis[p[i].pos]=true; 164 } 165 166 for(int i=0; i<9; i++) { 167 if(i%3!=2) {//第一步应是移动或举起 168 ops[i]=true; 169 dfs(i, 1); 170 ops[i]=false;//回溯 171 } 172 } 173 printf("%d\n", maxd); 174 return 0; 175 } 176 177 /* 178 9 3 3 179 4 3 1 180 2 3 3 181 182 15 183 */
标签:更新 位置 max math 不能 ring range 说明 情况下
原文地址:https://www.cnblogs.com/wwqzbl/p/13548796.html