題解鏈接:題解鏈接
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;
}