【模擬 貪心】B4207 [常州市賽 2021] 戰士|普及+

B4207 [常州市賽 2021] 戰士

題目背景

搬運自 http://czoj.com.cn/p/443。數據為民間數據。

題目描述

X \text X X 在玩一款操控戰士和怪物戰斗的游戲。戰士初始生命值為 iH \text{iH} iH 、初始攻擊力為 iA \text{iA} iA 。怪物只有一個,初始生命值為 H H H
戰斗是回合制的,且有一個回合數限制 M M M 。如果在 M M M 回合內怪物還沒有被殺死,小 X \text X X 就失敗了。在每個回合,戰士先行動,怪物再行動。
每當戰士行動,小 X \text X X 可以命令戰士做以下兩件事中的一件:

  • 攻擊,讓怪物的生命值減少當前戰士攻擊力的數值。
  • 磨刀,讓戰士攻擊力增加 dA \text{dA} dA

每當怪物行動,怪物會攻擊戰士,使戰士的生命值減少 C i C_i Ci? ,其中 i i i 為回合數。
當一個角色生命值小于等于 0 0 0 時,角色會死亡。

  • 如果怪物死亡,那么戰斗就結束了。
  • 如果戰士死亡,會立刻復活,將生命值和攻擊力恢復為初始數值。

現在小 X X X 想問問你,最少能在幾個回合內殺死怪物。

輸入格式

第一行, 5 5 5 個整數,分別為 iH,iA , H , dA , M \text{iH,iA},H,\text{dA},M iH,iA,H,dA,M,意義見問題描述。
第二行 M M M 個整數,表示第 i i i 個回合怪物的攻擊力 C i C_i Ci?

輸出格式

輸出一行一個整數表示最少能在幾個回合內殺死怪物。如果 M M M 回合內殺不死,輸出 -1

輸入輸出樣例 #1

輸入 #1

4 1 6 1 8
2 1 1 1 1 1 1 1

輸出 #1

5

說明/提示

樣例解釋

其中一種合法方案:

  • 第一回合:戰士磨刀,戰士攻擊力變為 2 2 2 ;怪物攻擊,戰士生命值變成 2 2 2
  • 第二回合:戰士攻擊,怪物生命值變為 4 4 4 ;怪物攻擊,戰士生命值變成 1 1 1
  • 第三回合:戰士攻擊,怪物生命值變為 2 2 2 ;怪物攻擊,戰士死亡后復活,生命值變為 4 4 4 ,攻擊力變為 1 1 1
  • 第四回合:戰士攻擊,怪物生命值變為 1 1 1 ;怪物攻擊,戰士生命值變成 3 3 3
  • 第五回合:戰士攻擊,怪物死亡。

數據范圍

本題共有 10 10 10 個測試點。
對于所有數據, 1 ≤ iH,iA , H ≤ 10 9 , 0 ≤ dA ≤ 10 9 , 1 ≤ C i ≤ M ≤ 2 × 10 5 1\le \text{iH,iA},H\le10^9,0\le \text{dA}\le10^9,1\le C_i\le M\le2\times10^5 1iH,iA,H109,0dA109,1Ci?M2×105

測試點編號 M M M特殊性質
1 1 1 ≤ 2 × 10 5 \le 2\times10^5 2×105 dA = 0 \text{dA}=0 dA=0
2 ~ 3 2\sim3 23 ≤ 20 \le20 20
4 ~ 5 4\sim5 45 ≤ 30 \le30 30
6 ~ 8 6\sim8 68 ≤ 10 3 \le10^3 103
9 ~ 10 9\sim10 910 ≤ 2 × 10 5 \le2\times10^5 2×105

模擬 貪心

a[i]表示,不輪回的情況下,戰士i回合操作的最大傷害。long long 型,如果大于LLONG_MAX/4,取LLONG_MAX/4。
dead=0,第dead回合輪回。hurt=0LL,記錄輪回前的傷害。HP=iH記錄戰士剩余生命值。
枚舉i = 1 to M
{ if(hurt + a[i-dead] >= H){return i ;}
if(C[i] >= HP){ HP=iH;dead=i;hurt += a[i-dead];}
else HP -= C[i]。}
return -1
計算a[i]
令磨刀x回合,顯然先磨刀再攻擊。總傷害,用a代替iA,d代替da:
( a + d × x ) ( i ? x ) = a × i + ( i × d ? a ) x ? d × x × x 式子一 \Large(a+d \times x)(i-x)=a\times i + (i\times d -a)x - d \times x\times x 式子一 (a+d×x)(i?x)=a×i+(i×d?a)x?d×x×x式子一
x 2 ? 2 x i × d ? a 2 d x^2-2x\frac{i\times d- a}{2d} x2?2x2di×d?a?
float f = i × d ? a d × 2.0 , 式子一 = ? d ( x ? f ) 2 + 某個常數 \large f =\large \frac{i\times d -a }{d \times 2.0},式子一=-d(x-f)^2 + 某個常數 f=d×2.0i×d?a?,式子一=?d(x?f)2+某個常數 如果f是整數,x取f時最大值。
如果f不是整數,向下取整或向上取整時是最大值。枚舉兩種情況。
注意 x 1 = ? f ? , x 2 = ? f ? x1 = \lfloor \ f \rfloor,x2 = \lceil \ f \rceil x1=??f?,x2=??f? 如果x1(x2) > i,取i。小于0,取0。
用3個樣例,過不了。暴力枚舉x,錯誤的樣例能過,但超時。
說明:F函數正確,x的極值錯誤。
自己構造了N組數據,沒發現錯誤。晚上睡覺前,靈光一現:a和d相差很大的時候是否有問題?
31號早上,一試果然如此? a = = 3 , d = = 1 a==3,d==1 a==3,d==1 暴力算法和計算的x不一致。

a[i] = max(F(x1, i), F(x2, i));auto tmp = F(0, i);for (int j = 1; j < i; j++) {tmp = max(tmp, F(j, i));}//Assert::AreEqual(tmp, a[i]);assert(tmp== a[i]);;

i為1時,暴力計算的是3,解方程的是4。
最終發現錯誤原因:賦值號打成了等號。

if (x1 >= i) { x1 == i; }

代碼

核心代碼

#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>
#include<assert.h>
#include<cstring>
#include<list>
#include<array>#include <bitset>
using namespace std;template<class T1, class T2>
std::istream& operator >> (std::istream& in, pair<T1, T2>& pr) {in >> pr.first >> pr.second;return in;
}template<class T1, class T2, class T3 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3>& t) {in >> get<0>(t) >> get<1>(t) >> get<2>(t);return in;
}template<class T1, class T2, class T3, class T4 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3, T4>& t) {in >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);return in;
}template<class T1, class T2, class T3, class T4, class T5, class T6, class T7 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3, T4,T5,T6,T7>& t) {in >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >> get<5>(t) >> get<6>(t);return in;
}template<class T = int>
vector<T> Read() {int n;cin >> n;vector<T> ret(n);for (int i = 0; i < n; i++) {cin >> ret[i];}return ret;
}
template<class T = int>
vector<T> ReadNotNum() {vector<T> ret;T tmp;while (cin >> tmp) {ret.emplace_back(tmp);if ('\n' == cin.get()) { break; }}return ret;
}template<class T = int>
vector<T> Read(int n) {vector<T> ret(n);for (int i = 0; i < n; i++) {cin >> ret[i];}return ret;
}template<int N = 1'000'000>
class COutBuff
{
public:COutBuff() {m_p = puffer;}template<class T>void write(T x) {int num[28], sp = 0;if (x < 0)*m_p++ = '-', x = -x;if (!x)*m_p++ = 48;while (x)num[++sp] = x % 10, x /= 10;while (sp)*m_p++ = num[sp--] + 48;AuotToFile();}void writestr(const char* sz) {strcpy(m_p, sz);m_p += strlen(sz);AuotToFile();}inline void write(char ch){*m_p++ = ch;AuotToFile();}inline void ToFile() {fwrite(puffer, 1, m_p - puffer, stdout);m_p = puffer;}~COutBuff() {ToFile();}
private:inline void AuotToFile() {if (m_p - puffer > N - 100) {ToFile();}}char  puffer[N], * m_p;
};template<int N = 1'000'000>
class CInBuff
{
public:inline CInBuff() {}inline CInBuff<N>& operator>>(char& ch) {FileToBuf();while (('\r' == *S) || ('\n' == *S) || (' ' == *S)) { S++; }//忽略空格和回車ch = *S++;return *this;}inline CInBuff<N>& operator>>(int& val) {FileToBuf();int x(0), f(0);while (!isdigit(*S))f |= (*S++ == '-');while (isdigit(*S))x = (x << 1) + (x << 3) + (*S++ ^ 48);val = f ? -x : x; S++;//忽略空格換行		return *this;}inline CInBuff& operator>>(long long& val) {FileToBuf();long long x(0); int f(0);while (!isdigit(*S))f |= (*S++ == '-');while (isdigit(*S))x = (x << 1) + (x << 3) + (*S++ ^ 48);val = f ? -x : x; S++;//忽略空格換行return *this;}template<class T1, class T2>inline CInBuff& operator>>(pair<T1, T2>& val) {*this >> val.first >> val.second;return *this;}template<class T1, class T2, class T3>inline CInBuff& operator>>(tuple<T1, T2, T3>& val) {*this >> get<0>(val) >> get<1>(val) >> get<2>(val);return *this;}template<class T1, class T2, class T3, class T4>inline CInBuff& operator>>(tuple<T1, T2, T3, T4>& val) {*this >> get<0>(val) >> get<1>(val) >> get<2>(val) >> get<3>(val);return *this;}template<class T = int>inline CInBuff& operator>>(vector<T>& val) {int n;*this >> n;val.resize(n);for (int i = 0; i < n; i++) {*this >> val[i];}return *this;}template<class T = int>vector<T> Read(int n) {vector<T> ret(n);for (int i = 0; i < n; i++) {*this >> ret[i];}return ret;}template<class T = int>vector<T> Read() {vector<T> ret;*this >> ret;return ret;}
private:inline void FileToBuf() {const int canRead = m_iWritePos - (S - buffer);if (canRead >= 100) { return; }if (m_bFinish) { return; }for (int i = 0; i < canRead; i++){buffer[i] = S[i];//memcpy出錯			}m_iWritePos = canRead;buffer[m_iWritePos] = 0;S = buffer;int readCnt = fread(buffer + m_iWritePos, 1, N - m_iWritePos, stdin);if (readCnt <= 0) { m_bFinish = true; return; }m_iWritePos += readCnt;buffer[m_iWritePos] = 0;S = buffer;}int m_iWritePos = 0; bool m_bFinish = false;char buffer[N + 10], * S = buffer;
};
class Solution {public:int Ans(int iH, int iA, const int H, int dA, vector<int>& C){				const int M = C.size();vector<long long> a(M + 1);auto F = [&](long long x,long long i) {const long long ll1 = dA * x + iA;const long long ll2 = i - x;if (LLONG_MAX / ll1 < ll2) { return (long long) H; }return ll1 *ll2 ;};for (long long i = 1; i <= M; i++) {if (0 == dA) {a[i] = iA * i;continue;}const long long f1 = i * dA - iA;const long long f2 = dA * 2LL;long long x1 = f1 / f2;					long long x2 = x1 + (0 != f1 % f2);if (x1 >= i) { x1 = i; }if (x2 >= i) { x2 = i; }if (x1 < 0) { x1 = 0; }if (x2 < 0) { x2 = 0; }a[i] = max(F(x1, i), F(x2, i));					}int dead = 0;long long hurt = 0, HP = iH;	for (int m = 1; m <= M; m++) {if (hurt + a[m - dead] >= H) { return m; }if (C[m-1] >= HP) {HP = iH; hurt += a[m - dead]; dead = m;  }else { HP -= C[m-1]; }}return -1;}};int main() {
#ifdef _DEBUGfreopen("a.in", "r", stdin);
#endif // DEBUG	ios::sync_with_stdio(0); cin.tie(nullptr);//CInBuff<> in; COutBuff<10'000'000> ob;	int iH,iA,H,dA,Q;cin>> iH >> iA >> H >> dA >> Q;auto C = Read<int>(Q);
#ifdef _DEBUG	printf("iH=%d,iA=%d,H=%d,dA=%d",iH,iA,H,dA);Out(C, ",C=");//Out(edge, ",edge=");		/*Out(que, ",que=");*///Out(ab, ",ab=");//Out(par, "par=");//Out(que, "que=");//Out(B, "B=");
#endif // DEBUG	auto res = Solution().Ans(iH, iA, H, dA, C);cout << res;return 0;
};

單元測試

	int iH, iA,  H,  dA;vector<int> C;TEST_METHOD(TestMethod01){iH = 4, iA = 1, H =1, dA = 0, C = { 2,1,1,1,1,1,1,1 };auto res = Solution().Ans(iH, iA, H, dA, C);AssertEx(1, res);}TEST_METHOD(TestMethod11){iH = 4, iA = 1, H = 6, dA = 1, C = { 2,1,1,1,1,1,1,1 };auto res = Solution().Ans(iH, iA, H, dA, C);AssertEx(5, res);}TEST_METHOD(TestMethod12){iH = 4, iA = 3, H = 4, dA =1 , C.assign(100'000,1);auto res = Solution().Ans(iH, iA, H, dA, C);AssertEx(2, res);}

# 擴展閱讀

我想對大家說的話
工作中遇到的問題,可以按類別查閱鄙人的算法文章,請點擊《算法與數據匯總》。
學習算法:按章節學習《喜缺全書算法冊》,大量的題目和測試用例,打包下載。重視操作
有效學習:明確的目標 及時的反饋 拉伸區(難度合適) 專注
聞缺陷則喜(喜缺)是一個美好的愿望,早發現問題,早修改問題,給老板節約錢。
子墨子言之:事無終始,無務多業。也就是我們常說的專業的人做專業的事。
如果程序是一條龍,那算法就是他的是睛
失敗+反思=成功 成功+反思=成功

視頻課程

先學簡單的課程,請移步CSDN學院,聽白銀講師(也就是鄙人)的講解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成戰斗了,為老板分憂,請學習C#入職培訓、C++入職培訓等課程
https://edu.csdn.net/lecturer/6176

測試環境

操作系統:win7 開發環境: VS2019 C++17
或者 操作系統:win10 開發環境: VS2022 C++17
如無特殊說明,本算法用**C++**實現。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85032.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85032.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85032.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

37-Oracle 23 ai Shrink Tablespace(一鍵收縮表空間)

小伙伴們有沒有經歷過&#xff0c;超大表和超大數據的導入后&#xff0c;數據被刪除了&#xff0c;然而空間遲遲不釋放&#xff0c;存儲添置又跟不上&#xff0c;業務空間告警的時候。收縮就很必須了&#xff0c;然而收縮需謹慎&#xff0c;數據大過天。DBMS_SPACE.SHRINK_TABL…

我自己動手寫了一個MySQL自動化備份腳本,基于docker

MySQL自動化備份Docker方案 該方案僅需通過 Docker Compose 就能輕松完成部署。你可以自由配置數據庫連接信息&#xff0c;無論是遠程數據庫&#xff0c;還是本地數據庫&#xff0c;都能實現無縫對接。在備份頻率設置上&#xff0c;支持按固定秒數間隔執行備份任務&#xff0c…

leetcode23-合并K個升序鏈表

leetcode 23 思路 遍歷所有鏈表收集節點&#xff1a;將每個鏈表的節點斷開其 next 指針后存入數組對數組進行排序&#xff1a;使用 JavaScript 的內置 sort 方法對節點數組按值排序重新連接排序后的節點&#xff1a;遍歷排序后的數組&#xff0c;依次連接每個節點形成新鏈表…

(十六)GRU 與 LSTM 的門控奧秘:長期依賴捕捉中的遺忘 - 更新機制對比

1 長期依賴捕捉能力的核心差異 1.1 信息傳遞路徑&#xff1a;細胞狀態 vs 單一隱藏狀態 LSTM的“信息高速公路”機制 LSTM通過獨立的細胞狀態&#xff08;Cell State&#xff09; 傳遞長期信息&#xff0c;該狀態可視為“直接通路”&#xff0c;允許信息跨越多個時間步而不被中…

HTTP 請求報文 方法

在 HTTP 請求報文 中&#xff0c;方法&#xff08;Method&#xff09; 是用來說明客戶端希望對服務器資源執行的操作。它出現在 HTTP 報文的第一行&#xff0c;稱為 請求行&#xff0c;格式如下&#xff1a; METHOD Request-URI HTTP-Version例如&#xff1a; GET /index.h…

【深度解析】Java高級并發模式與實踐:從ThreadLocal到無鎖編程,全面避坑指南!

&#x1f50d; 一、ThreadLocal&#xff1a;線程隔離的利器與內存泄露陷阱 底層原理揭秘&#xff1a; 每個線程內部維護ThreadLocalMap&#xff0c;Key為弱引用的ThreadLocal對象&#xff0c;Value為存儲的值。這種設計導致了經典內存泄露場景&#xff1a; // 典型應用&#…

使用存儲型 XSS 竊取 cookie 并發送到你控制的服務器

&#x1f9ea; 第一步&#xff1a;準備監聽服務接收 cookie 在你的本機&#xff08;非容器&#xff09;或 DVWA 所在主機運行以下 Python 監聽代碼&#xff0c;用于接收竊取的 cookie&#xff1a; 啟動 HTTP 接收服務 # 在本機終端運行&#xff0c;監聽 8081 端口&#xff0…

WebDebugX和多工具組合的移動端調試流程構建:一個混合App項目的實踐案例

前段時間參與了一個跨平臺的醫療服務 App 項目&#xff0c;整體架構采用 Flutter 封裝原生模塊&#xff0c;部分功能模塊嵌套 WebView 加載 H5 頁面。開發過程中我們頻繁遇到 Web 頁面在移動端表現異常的問題&#xff0c;比如樣式錯亂、請求失敗、性能延遲等&#xff0c;而這些…

圖形編輯器基于Paper.js教程29:基于圖層的所有矢量圖元的填充規則實現

背景 在lightburn中&#xff0c;對于填充圖層&#xff0c;有這樣一個隱藏的邏輯&#xff0c;那就是&#xff0c;在加工時&#xff0c;填充規則是以填充圖層的所有元素進行計算的&#xff0c;什么意思那&#xff1f; 如果你在填充圖層中畫了兩個圖形&#xff0c;一個圓&#xf…

Python 函數實戰指南:提升編程效率的實用技巧

在 Python 編程的世界里&#xff0c;函數是構建高效代碼的基石。掌握實用的函數技巧不僅能讓代碼更加簡潔優雅&#xff0c;還能顯著提升開發效率。我們一起將結合實際案例&#xff0c;深入剖析 Python 函數的使用技巧&#xff0c;幫助開發者在日常開發中事半功倍。 一、基礎函數…

OPenCV CUDA模塊圖形變換----構建透視變換映射表函數buildWarpPerspectiveMaps()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該函數用于構建一個透視變換&#xff08;Perspective Transform&#xff09;的映射表&#xff08;xmap / ymap&#xff09;&#xff0c;可用于后…

tcping工具使用指南

tcping是一個用于測試TCP端口連通性的工具&#xff0c;它類似于傳統的ping命令&#xff0c;但工作在傳輸層(TCP)而不是網絡層(ICMP)。 基本功能 tcping的主要功能包括&#xff1a; 測試目標主機特定TCP端口是否開放 測量TCP連接建立時間 統計丟包率和響應時間 安裝方法 …

CSP 2024 入門級第一輪(88.5)

4. 以下哪個序列對應數字 00 至 88 的 44 位二進制格雷碼&#xff08;Gray code&#xff09;&#xff1f;&#xff08; &#xff09; A. 0000, 0001, 0011, 0010, 0110, 0111, 0101, 1000 B. 0000, 0001, 0011, 0010, 0110, 0111, 0100, 0101 C. 0000, 0001, 0011, 0010, …

三菱FX-5U系列入門到精通

第2章 中間繼電器 繼電器工作模式:線圈得電,常開觸點閉合,常閉觸點斷開。總結:中間繼電器線圈電壓分為:24VDC 110VAC 220VAC 380VAC PLC控制柜中常用的是24VDC比較多,而動力電柜中或者控制風機水泵的電柜中220VAC比較多。大部分選擇24VDC,然后用觸點控制220或者380,說白…

簡歷模板1——王明 | 高級數據挖掘工程師 | 5年經驗

王明 | 高級數據挖掘工程師 | 5年經驗 &#x1f4f1; (86) 189-xxxx-xxxx | &#x1f4e7; wangmingemail.com | &#x1f4cd; 深圳市 &#x1f4bb; GitHub | &#x1f454; LinkedIn &#x1f4bc; 工作經歷 ?科技前沿集團 | 高級數據挖掘工程師 &#x1f4c5; 2021.06 …

【JVM】- 內存模式

Java內存模型&#xff1a;JMM&#xff08;Java Memory Model&#xff09;&#xff0c;定義了一套在多線程環境下&#xff0c;讀寫共享數據&#xff08;成員變量、數組&#xff09;時&#xff0c;對數據的可見性&#xff0c;有序性和原子性的規則和保障。 原子性 問題分析 【問…

AQS獨占模式——資源獲取和釋放源碼分析

AQS資源獲取&#xff08;獨占模式&#xff09; Node節點類 static final class Node {//標記當前節點的線程在共享模式下等待。static final Node SHARED new Node();//標記當前節點的線程在獨占模式下等待。static final Node EXCLUSIVE null;//waitStatus的值&#xff0c…

壓測過程中TPS上不去可能是什么原因

進行性能分析 接口沒有報錯或者錯誤率低于1%&#xff0c;繼續增加并發還是一樣&#xff0c;這個時候需要考慮幾點 1.是否觸發限流&#xff0c;比如waf、Nginx等情況&#xff0c;有沒有一些限流的情況&#xff0c;如果觸發了限流&#xff0c;請求是沒有達到后端的&#xff0c;所…

Golang 解大整數乘法

文章目錄 Golang 解大整數乘法問題描述&#xff1a;LeetCode 43. 字符串相乘思路Golang 代碼 Golang 解大整數乘法 在初學 C 語言的時候&#xff0c;我們一定接觸過“字符串相加”或“字符串相乘”之類的問題&#xff0c;對于初學者而言&#xff0c;這類問題的難度一般來說是比…

web3-區塊鏈的技術安全/經濟安全以及去杠桿螺旋(經濟穩定)

web3-區塊鏈的技術安全/經濟安全以及去杠桿螺旋&#xff08;經濟穩定&#xff09; 三個基本設計問題 技術安全 在技術結構中對其進行原子級的、瞬時利用&#xff08;無風險&#xff09; 無風險&#xff0c;因為攻擊者的結果還是二進制的&#xff1a; 只會是攻擊成功 獲利或…