国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

藍橋杯 算法訓練 Lift and Throw

2019-11-08 01:51:12
字體:
來源:轉載
供稿:網友
 算法訓練 Lift and Throw  時間限制:3.0s   內存限制:256.0MB    問題描述  給定一條標有整點(1, 2, 3, ...)的射線. 定義兩個點之間的距離為其下標之差的絕對值.  Laharl, Etna, Flonne一開始在這條射線上不同的三個點, 他們希望其中某個人能夠到達下標最大的點.  每個角色只能進行下面的3種操作, 且每種操作不能每人不能進行超過一次.  1.移動一定的距離  2.把另一個角色高舉過頭  3.將舉在頭上的角色扔出一段距離  每個角色有一個movement range參數, 他們只能移動到沒有人的位置, 并且起點和終點的距離不超過movement range.  如果角色A和另一個角色B距離為1, 并且角色B沒有被別的角色舉起, 那么A就能舉起B. 同時, B會移動到A的位置,B原來所占的位置變為沒有人的位置. 被舉起的角色不能進行任何操作, 舉起別人的角色不能移動.同時, 每個角色還有一個throwing range參數, 即他能把舉起的角色扔出的最遠的距離. 注意, 一個角色只能被扔到沒有別的角色占據的位置. 我們認為一個角色舉起另一個同樣舉起一個角色的角色是允許的. 這種情況下會出現3個人在同一個位置的情況. 根據前面的描述, 這種情況下上面的兩個角色不能進行任何操作, 而最下面的角色可以同時扔出上面的兩個角色. 你的任務是計算這些角色能夠到達的位置的最大下標, 即最大的數字x, 使得存在一個角色能夠到達x.輸入格式  輸入共三行, 分別為Laharl, Etna, Floone的信息.  每一行有且僅有3個整數, 描述對應角色的初始位置, movement range, throwing range.  數據保證3個角色的初始位置兩兩不相同且所有的數字都在1到10之間.</div>輸出格式  僅有1個整數, 即Laharl, Etna, Flonne之一能到達的最大距離.樣例輸入9 3 34 3 12 3 3樣例輸出15樣例說明  一開始Laharl在位置9, Etna在位置4, Flonne在位置2.  首先, Laharl移動到6.  然后Flonne移動到位置5并且舉起Etna.  Laharl舉起Flonne將其扔到位置9.  Flonne把Etna扔到位置12.  Etna移動到位置15.
#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;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 墨江| 依兰县| 沂南县| 天台县| 如东县| 理塘县| 祥云县| 墨江| 盈江县| 武定县| 科技| 油尖旺区| 靖边县| 江津市| 富裕县| 无极县| 西昌市| 平潭县| 且末县| 丹江口市| 安阳市| 红桥区| 建宁县| 阳信县| 湖北省| 涿州市| 临城县| 乌兰察布市| 称多县| 榆中县| 武宁县| 江城| 麻城市| 贺兰县| 都江堰市| 定州市| 浑源县| 朔州市| 枣阳市| 响水县| 榕江县|