(博弈论 高精度小数)51NOD 1185 威佐夫游戏 V2
Posted ekalos-blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(博弈论 高精度小数)51NOD 1185 威佐夫游戏 V2相关的知识,希望对你有一定的参考价值。
有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。
例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000) 第2 - T + 1行:每行2个数分别是2堆石子的数量,中间用空格分隔。(1 <= N <= 10^18)
Output
共T行,如果A获胜输出A,如果B获胜输出B。
Input示例
3 3 5 3 4 1 9
Output示例
B A A
解:众所周知,计算机表示的小数是一定程度内精确的,如本题(sqrt(5.0) + 1) / 2,double只精确到第16位(double保证15到16位有效数字,不是15到16位小数),而本题精度要求却在16位之后,所以我们需要找到更高精度的黄金比例,并且改进计算方式因为直接使用double还是会丢失精度。
道理我都懂,但是我们预设的高精度黄金比例是怎么得到呢(不承认查阅资料)?
1 #include<stdio.h> 2 3 #define M (int)1e9 4 5 long long tmp[3] = {618033988,749894848,204586834 }; //更精确的(sqrt(5.0) + 1) / 2的小数部分 6 7 int main() 8 { 9 int t; 10 while (scanf_s("%d", &t) != EOF) 11 { 12 while (t--) 13 { 14 long long a, b, temp, num[2]; 15 scanf_s("%lld%lld", &a, &b); 16 if (a < b) 17 { 18 temp = a; 19 a = b; 20 b = temp; 21 } 22 a -= b; 23 num[0] = a / M; 24 num[1] = a % M; 25 temp = tmp[2] * num[1]; 26 temp = num[1] * tmp[1] + num[0] * tmp[2] + temp / M; 27 temp = num[1] * tmp[0] + num[0] * tmp[1] + temp / M; 28 temp = num[0] * tmp[0] + temp / M; 29 a += temp; 30 if (a == b) printf("B "); 31 else printf("A "); 32 } 33 } 34 return 0; 35 }
以上是关于(博弈论 高精度小数)51NOD 1185 威佐夫游戏 V2的主要内容,如果未能解决你的问题,请参考以下文章