首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

BZOJ 3856 Monster (不公平博弈):三條件判定必勝邏輯

     編輯:關於C++

題目重述

同 BZOJ 3856 Monster,敘述為「不公平博弈」。貓咪初始血量 h,先手每回合砍 a 點傷害,貓咪回手回 b 點血,先手連續 k 回合攻擊後休息 1 回合。判斷先手能否砍死貓咪。

三個充分必要條件 (任一成立即 YES)

  1. OTK (一回合秒殺):h <= a
  2. 第 k 回合內砍死:前 k 回合貓咪回血 k-1 次,總傷害 k*a,總回血 (k-1)*b,需 k*a >= h + (k-1)*b。等價 h - k*(a-b) - b <= 0。
  3. 長期每輪淨扣血:一個完整週期 (k 攻擊 + 1 休息) 共 k+1 回合,貓咪受傷 k*a,回血 (k+1)*b。若 k*a > (k+1)*b,則每輪貓咪血量遞減,最終必死。等價 k*(b-a) + b < 0。

簡潔代碼

#include 
using namespace std;
long long h, a, b, k;
int cnt;
int main() {
    while (cin >> h >> a >> b >> k, h||a||b||k) {
        if (h <= a || h - k*(a-b) - b <= 0 || k*(b-a) + b < 0)
            printf("Case #%d: YES\n", ++cnt);
        else
            printf("Case #%d: NO\n", ++cnt);
    }
    return 0;
}

條件推導驗證

  • 條件 2:第 k 次攻擊前,貓咪已回血 k-1 次。血量 = h - (k-1)*a + (k-1)*b。第 k 次攻擊後血量 = h - k*a + (k-1)*b。需 ≤ 0 → k*a >= h + (k-1)*b。
  • 條件 3:一輪 (k 攻擊 + 1 休息) 淨傷害 = k*a - (k+1)*b。若 > 0,血量單調遞減,必死。

注意事項

  • 使用 long long 避免乘法溢位。
  • 輸入以四個 0 終止。
  • 案例編號從 1 開始遞增。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved