#include <bits/stdc++.h>#include <stdio.h>#include <string.h>#define TRUE 1#define FALSE 0#define max(a, b) a > b ? a : b//定義數組大小為4,從一開始,空出下標為0,方便計算int x[4]; //三個人的位置int l[4]; //三個人的機動性(可移動距離)int t[4]; //三個人的拋的距離int ans = 0; //經過操作后的最遠距離,初始化為0int w[4]; //初始化為0,0表示可以進行操作,非零表示不可以int p[4]; //初始化為0,表示a[i]所舉起的人int a[4] = {3, 3, 3, 3}; //初始化為3,表人的狀態,這里a對應的二進制為0011,后三位分別是三個動作:拋出,舉起,移動。0(無意義)0(不可拋出)1(未進行舉起)1(未進行移動)。這道題中,a只有六個可能值:0(0000)、1(0001)、2(0010)、3(0011)、4(0100)、5(0101),表示人的六種狀態//bool類型int near(int s){ int i = 1; for (; i <= 3; i++) { if (s == x[i] + 1 || s == x[i] - 1) { return TRUE; } } return FALSE;}//dfs深度遍歷void dfs(int d){ int i = 1, j = 1, e = 0; //每次都取最遠(大)的位置 for (; i <= 3; i++) { ans = max(ans, x[i]); } for (i = 1; i <= 3; i++) { //是否可以進行操作 if (w[i]) { continue; } //a[i] == 1 || a[i] == 3(未進行移動且不可拋出) if ((a[i] & 1) && !(a[i] & 4)) { for (j = 1; j <= l[i]; j++) //移動 { x[i] += j; //a[i]向前移動j a[i] ^= 1; //已移動 if (near(x[i]) || j == l[i]) //如果a[i]移動后的位置旁邊有人或者移動距離達到上限 { dfs(d + 1); } x[i] -= j; //歸位 x[i] -= j; //a[i]向后移動j if (near(x[i]) || j == l[i]) //如果a[i]移動后的位置旁邊有人或者移動距離達到上限 { dfs(d + 1); } x[i] += j; //歸位 a[i] ^= 1; //還原為未移動 } } //a[i] == 2 || a[i] == 3 || a[i] == 5(未進行舉起) if (a[i] & 2) { for (j = 1; j <= 3; j++) //舉起 { if (i != j && !w[j] && t[i] > 0) //是否可以進行操作 { if (x[i] == x[j] + 1 || x[j] == x[i] + 1) //a[i]附近是否有人 { w[j] = 1; //即將舉起(拋出)j,拋出前將j是否可操作標記變更為否 a[i] ^= 2; //已舉起 a[i] ^= 4; //可拋出 p[i] = j; //記錄a[i]舉起(拋出)了j e = x[j]; //記錄a[j]的舉起前位置 x[j] = -j; //a[j](被舉起)的位置定為負數,只作用于下一層遞歸時的取最遠位置的循環 dfs(d + 1); x[j] = e; //歸位 w[j] = 0; //還原為可以進行操作 a[i] ^= 2; //還原為未舉起 a[i] ^= 4; //還原為不可拋出 } } } } //a[i] == 4 || a[i] == 5(可拋出) if (a[i] & 4) { for (j = 1; j <= t[i]; j++) //拋出 { w[p[i]] = 0; //變更a[j]為可操作(以下a[j]指a[i]所舉起的人) a[i] ^= 4; //不可拋出 e = x[p[i]]; //記錄a[j]被舉起前位置 x[p[i]] = x[i] + j; //拋出a[j],并更新a[j]位置 if (near(x[p[i]]) || j == t[i]) //如果a[j]被拋出后的位置旁邊有人或者拋出距離達到上限 { dfs(d + 1); } x[p[i]] -= j; //歸位 x[p[i]] -= j; //a[j]向后拋出j if (near(x[p[i]]) || j == t[i]) //如果a[j]被拋出后的位置旁邊有人或者拋出距離達到上限 { dfs(d + 1); } x[p[i]] = e; //還原a[j]為未舉起前的位置 a[i] ^= 4; //還原a[j]為可拋出 w[p[i]] = 1; //還原a[j]為不可操作 } } } return ;}int main(){ int i = 1; //鍵入每個人的信息 for (; i <= 3; i++) { scanf("%d %d %d", &x[i], &l[i], &t[i]); } //深度優先遍歷 dfs(1); //輸出最遠距離 PRintf("%d/n", ans); return 0;}
|
新聞熱點
疑難解答