AtCoder Beginner Contest 153 題解

題解鏈接:題解鏈接

RD是輸入,OT是輸出

A – SERVAL VS MONSTER
鏈接:
A題

題意:
給你怪物血量H和攻擊一次扣A血,問至少要攻擊幾次能使怪物的血量小於或者等於0

解法:
按題意模擬,考慮到循環減去時間會較長,故判斷奇偶後除求解攻擊次數

代碼

int main(){
    LL h, a;
    RD(h, a);
    if (h%a == 0) cout << h/a << '\n';
    else  cout << h/a+1 << '\n';
}

B – COMMON RACCOON VS MONSTER
鏈接:
B題

題意:
怪物有H滴血,有N種攻擊方式,每種攻擊方式能造成ai的傷害,問每種攻擊方式攻擊一次是否能夠使怪物血量小於或者等於0

解法:
模擬,直接扣最後判斷即可

代碼:

int main(){
    int h, n; RD(h, n);
    for(int i = 0; i < n; i++){
        LL x; RD(x);
        h-=x;
    }
    if (h <= 0) OT("Yes\n");
    else OT("No\n");
}

C – FENNEC VS MONSTER
鏈接:
c題

題意:
Fennec 和 N 個怪物進行戰鬥,第 i 個怪物的血量爲 Hi ,Fennec可以進行兩種操作,一種攻擊扣一滴血,另一種特殊攻擊,能夠使一個怪物的血量降到0,但是特殊攻擊只能進行K次,求需要進行幾次攻擊

解法:
刪去K個H大的怪物,剩餘的平a

代碼:

const int N = 2e5+50;
int H[N];
int main(){
    LL n, k; RD(n, k);
    REP(i, n) RD(H[i]);
    sort(H, H+n);
    LL ans = 0;
    for(int i = 0; i < n-k; i++){
        ans += H[i];
    }
    OT(ans);
}

D – CARACAL VS MONSTER
鏈接:
D題

題意:

怪物有H滴血,有兩種操作方式,問需要操作幾次?
如果 H > 1進行分裂和扣半血操作(扣半血是下取整操作)【這是算一次操作】
如果 H <= 1直接血量降爲 0

解法:
仔細看樣例會知道這是一題數學題,多列樣例猜測規律
血量H 操作次數ans

1 1
2 3
3 3
4 7

1000000000000 1099511627775
畫出圖來後知道在大於1的時候一定要經過分裂,直到分裂扣血到1停止

int main(){
    LL h; RD(h);
    LL ans = 0, x = 1;
    while(x <= h){ans+=x;x<<=1;}
    OT(ans);
}

E – CRESTED IBIS VS MONSTER
類型:
完全揹包問題、動態規劃

鏈接:
E題

題意:
怪物有H滴血,魔法師有N個技能,每進行i技能時,魔法師自身消耗b[ i ]法力值,怪物扣血a[ i ],求使怪物血量小於等於0,最少消耗的法力值

解法:
H滴血相當於揹包容量,N個技能相當於N種選擇,a[ i ] 相當於物品重量, b[ i ]相當於每個物品的價值
轉移方程

int x = max(0, j-a[i]);
dp[j] = min(dp[j],dp[x]+b[i]);

即選擇下一個技能的話就要加上下一個技能的b[ i ],不選擇的話就不加

代碼:

const int maxn = 1e5+10;
int a[maxn], b[maxn];
const int N = 1e4+10;
int dp[N]= {0};
int main(){
    int h, n; RD(h, n);
    for(int i = 1; i <= n; i++){
        RD(a[i], b[i]);
    }
    FOR_1(i, 1, h) dp[i] = 1e9; dp[0] = 0;
    FOR_1(i, 1, n){
        FOR_1(j, 0, h){
            int x = max(0, j-a[i]);
            dp[j] = min(dp[j],dp[x]+b[i]);
        }
    }
    OT(dp[h]);
}

F – SILVER FOX VS MONSTER
鏈接:
F題

題意:
銀狐和N個怪物戰鬥。N個怪物在一條線上,第i個怪物站在第xi個位置,並且具有hi點血量,現在進行激光炮對x位置進行轟擊,會對x-D 到 x+D範圍內怪物造成傷害,求解轟擊次數。

解法:
建立一個c[ i ]計算每個點位的炮擊次數need,即c[ i ]+=need,計算最遠的炮擊位置c[i+1] += c[i],超出範圍的都會扣除need,所以+c[i]-need就會抵消了

代碼:

const int N = 2e5+50;
LL c[N];
struct mos{
    int x;
    int h;
} p[N];
bool cmp(mos a, mos b){
    return a.x < b.x;
}
int main(){
    int n, a, d; RD(n, d, a);
    FOR_1(i, 1, n){
        RD(p[i].x, p[i].h);
    }
    sort(p+1, p+n+1, cmp);
    LL ans = 0;
    for (int i = 1,j = 1; i <= n; i++)
    {
        while(j <= n && p[j].x <= p[i].x + 2*d)
            ++j;
        LL need = max((p[i].h - c[i]*a + a - 1)/a, 0ll);
        ans += need;
        c[i] += need;
        c[j] -= need;
        c[i+1] += c[i];
    }
    cout << ans << endl;
}
發佈了22 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章