HDU-1517 A Multiplication Game
A Multiplication Game
巴什博奕
这题的控制范围在于 x * 18
可以观察:
-
必败态 \([n, +\infty]\)
-
必胜态
[n / 9, n)
-
必败态
[n / 9 / 2, n / 9)
-
必胜态
[n / 9 / 2 / 9, n / 9 / 2)
可发现必败态是 [n / (k * 18), 2 * n / (k * 18))
因此我们只要考虑将 n 一直除到 18 以下,就可以判断第一步,先手能否将状态转换为必败态,也就是判断此时的 n 与 9 的关系
#include <iostream>
using namespace std;
int main()
{
double n;
while (cin >> n) {
while (n > 18) n /= 18;
if (n <= 9) cout << "Stan wins." << endl;
else cout << "Ollie wins." << endl;
}
return 0;
}
通过这道题,我还发现我总是会以一种很奇怪的方式水过一道题
例如直接搜索sg函数
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
map<ll, int>sg;
ll n;
// 1 必输 2 必胜
int dps(ll x)
{
if(x >= n) return 1;
if(sg[x]) return sg[x];
int f = 1;
for(int i=9; i>=2 && f == 1; i--)
if(dps(x * i) == 1) f = 2;
return sg[x] = f;
}
int main()
{
while(cin >> n)
{
sg.clear();
int ans = dps(1);
if(ans == 1) cout << "Ollie wins." << endl;
else cout << "Stan wins." << endl;
}
return 0;
}