[51Nod 1185 威佐夫游戏 V2]Wythoff Game+乘法模拟
2016-10-16 20:37
507 查看
[51Nod 1185 威佐夫游戏 V2]Wythoff Game+乘法模拟
题目链接:[51Nod 1185 威佐夫游戏 V2]题意描述:有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。
例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。
注意:这个题目每堆石子的数目是在[1,1018]范围内。
解题思路:根据Wythoff 博弈定理:当且仅当a=⌊k∗5√+12⌋,b=a+k时,先手失败;否则后手失败。由于题目给定的石子数目很大,所以不能用浮点数直接进行运算。[tips:5√+12=1.6180339887498948482045868343656...],这里用到了乘法模拟的方法,来增大精度。
这题还有一个Java大数的做法, 请参考另外一篇博客《 [hdu 5973 Game of Taking Stones] Wythoff Game+大数运算 》
#include <map> #include <set> #include <queue> #include <cmath> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; //#pragma comment(linker, "/STACK:1024000000,1024000000") #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w",stdout) #define fst first #define snd second #define rep(i, f, t) for(int i = (f); i <= (t); i++) //typedef __int64 LL; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PII; const ULL MOD = 1000000000; /// 1e9 int T; ULL A, B; ULL X[] = {618033988, 749894848, 204586834}; ULL Y[2], Z[4]; bool check(ULL x, ULL y) { if(x > y) swap(x, y); /// 转化为1e9进制数的模拟乘法,计算k*618033988749894848204586834,结果保存在Z[]中 ULL k = y - x, temp = 0; Y[0] = k / MOD, Y[1] = k % MOD; Z[3] = (temp = X[2] * Y[1] + temp) % MOD, temp /= MOD; Z[2] = (temp = X[1] * Y[1] + X[2] * Y[0] + temp) % MOD, temp /= MOD; Z[1] = (temp = X[0] * Y[1] + X[1] * Y[0] + temp) % MOD, temp /= MOD; Z[0] = (temp = X[0] * Y[0] + temp) % MOD, temp /= MOD; return x == temp * MOD + k + Z[0]; } int main() { #ifndef ONLINE_JUDGE FIN; #endif // ONLINE_JUDGE scanf("%d", &T); while(T --) { cin >> A >> B; puts(check(A, B) ? "B" : "A"); } return 0; }
补充一个Java代码:
import java.math.BigDecimal; import java.util.Scanner; public class Main { static BigDecimal sqrt_five, G; static BigDecimal two, five; public static void init() { two = new BigDecimal(2); five = new BigDecimal(5); BigDecimal low, high, mid; low = new BigDecimal(0); high = new BigDecimal(5); mid = new BigDecimal(0); for(int i = 0; i < 100; i++) { mid = low.add(high).divide(two); if(mid.multiply(mid).compareTo(five) > 0) high = mid; else low = mid; } sqrt_five = mid; // G = (sqrt(5) + 1) / 2; G = sqrt_five.add(BigDecimal.ONE).divide(two); } public static void main(String[] argv) { BigDecimal a, b, c, left, right; init(); int T; Scanner input = new Scanner(System.in); T = input.nextInt(); while ((T --) != 0) { a = input.nextBigDecimal(); b = input.nextBigDecimal(); if (a.compareTo(b) > 0) { c = a; a = b; b = c; } left = b.subtract(a).multiply(G); right = a; // 向下取整。统一精度。 left = left.setScale(0, BigDecimal.ROUND_DOWN); right = right.setScale(0, BigDecimal.ROUND_DOWN); if(left.compareTo(right) == 0) System.out.println("B"); else System.out.println("A"); } return; } }
相关文章推荐
- 51nod 1185 威佐夫游戏 V2
- 51NOD 1185 威佐夫游戏 V2(大数运算 JAVA 模板)
- 51nod 1185 威佐夫游戏 V2
- HDU 5973Game of Taking Stones 51nod 1185 威佐夫游戏 V2(威佐夫博弈)
- 51nod--1185 威佐夫游戏 V2 (博弈, 乘法模拟)
- 51nod 1185 威佐夫游戏V2
- 51NOD 1185 威佐夫游戏 V2(博弈论 + 减少精度)
- 51Nod 1185 威佐夫游戏 V2 (威佐夫博弈)
- 51nod 1185 威佐夫游戏 V2
- 51Nod-1185-威佐夫游戏 V2
- 51nod 1185 威佐夫游戏 V2 (博弈+大数乘法模拟)
- 51nod 1185 威佐夫游戏 V2
- 51nod 1185 威佐夫游戏 V2 (用乘法模拟解决大数精度问题)
- 51nod 1185 威佐夫游戏 V2(威佐夫博弈)
- 51NOD 1185 威佐夫游戏 V2(威佐夫博弈)
- 1185 威佐夫游戏v2,卡精度,乘法模拟
- 1185 威佐夫游戏 V2 博弈论 + 大整数乘法
- 51nod-1185【博弈论】威佐夫游戏【未完】
- 51nod-1185【博弈论】威佐夫游戏【未完】
- 51 NOD _ 1185 威佐夫游戏 V2