結果
| 問題 |
No.3112 Decrement or Mod Game
|
| コンテスト | |
| ユーザー |
aaaaaaaaaaa
|
| 提出日時 | 2025-04-19 00:56:40 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 3,081 bytes |
| コンパイル時間 | 944 ms |
| コンパイル使用メモリ | 81,916 KB |
| 実行使用メモリ | 814,464 KB |
| 最終ジャッジ日時 | 2025-04-19 00:56:46 |
| 合計ジャッジ時間 | 5,566 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 3 |
| other | MLE * 1 -- * 64 |
ソースコード
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <utility>
using namespace std;
typedef long long ll;
// memo[0] for Alice's turn, memo[1] for Bob's turn
// value is 1 if the player whose turn it is wins, 0 otherwise.
map<pair<ll, ll>, int> memo[2];
// Returns 1 if the current player (with my_num) wins against opponent (with opp_num), 0 otherwise.
// Assumes my_num > 0 and opp_num > 0 when called initially.
int solve(ll my_num, ll opp_num, bool is_my_turn) {
// If we reach a state where memo already has the answer, return it.
pair<ll, ll> state = {my_num, opp_num};
int player_idx = is_my_turn ? 0 : 1;
if (memo[player_idx].count(state)) {
return memo[player_idx][state];
}
// Check immediate win conditions for the current player: make my_num = 0
// Move 1: Decrease my_num by 1
if (my_num == 1) { // my_num - 1 becomes 0
return memo[player_idx][state] = 1; // Current player wins
}
// Move 2: Modulo my_num by opp_num (if possible)
if (opp_num <= my_num && my_num % opp_num == 0) { // my_num % opp_num becomes 0
return memo[player_idx][state] = 1; // Current player wins
}
// If no immediate win, explore non-winning moves.
// Current player wins if *any* non-winning move leads to a state where the opponent loses.
bool can_win = false;
// Option 1: Decrease my_num by 1 (results in my_num - 1 > 0)
// New state for opponent: opponent has opp_num, I have my_num - 1. State (opp_num, my_num - 1) for opponent's turn.
// Current player wins if solve(opp_num, my_num - 1, !is_my_turn) returns 0 (opponent loses).
if (my_num > 1) { // Only consider this move if my_num - 1 > 0 (my_num == 1 is immediate win)
if (solve(opp_num, my_num - 1, !is_my_turn) == 0) {
can_win = true;
}
}
// If already found a winning move, no need to check others
if (can_win) {
return memo[player_idx][state] = 1;
}
// Option 2: Modulo my_num by opp_num (if possible and non-zero). The resulting number my_num' = my_num % opp_num.
// New state for opponent: opponent has opp_num, I have my_num % opp_num. State (opp_num, my_num % opp_num) for opponent's turn.
// Current player wins if solve(opp_num, my_num % opp_num, !is_my_turn) returns 0 (opponent loses).
if (opp_num <= my_num) { // Modulo is possible
if (my_num % opp_num != 0) { // If not an immediate win by modulo
if (solve(opp_num, my_num % opp_num, !is_my_turn) == 0) {
can_win = true;
}
}
}
// Store and return result
return memo[player_idx][state] = can_win ? 1 : 0;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ll A, B;
cin >> A >> B;
// Alice goes first, has A, Bob has B.
// solve(A, B, true) checks if the player with A (Alice) wins starting the game with numbers (A, B).
if (solve(A, B, true) == 1) {
cout << "Alice" << endl;
} else {
cout << "Bob" << endl;
}
return 0;
}
aaaaaaaaaaa