标签:博弈 int return 两堆 printf 佐夫 validate include
入门题:POJ1067
威佐夫详解
例如,两堆石子,两种取法,要么在一堆中取任意数量,要么在两堆中取同等数量,取完者胜。
根据前人研究,先手的必败局为(m,n)【其中 min(m,n) == | m - n | *1.618】
在当前局势必胜的情况下,可以通过枚举差值使其满足必败局的条件,得到下一步的取法。
#include <iostream>
#include<cstdio>
#include<math.h>
using namespace std;
const double g = (sqrt(5.0) + 1) / 2; //1.618 这种算法比较准确
bool validate(int a,int b){
if(a > b)swap(a,b);
int k = b - a;
if(a == (int)(g * k)) return true; //注意int是下取整
else return false;
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m) != EOF){
if(validate(n,m))printf("0\n");
else {
printf("1\n");
//在两堆石子中同时取,从1枚举到最小数
int a = min(n,m);
int b = max(n,m);
int ans = 0;
//取完之后让对手面对必败局
for(int i = 1; i <= a;++i){
if(validate(a-i,b-i)) printf("%d %d\n",a-i,b-i);
}
//仅从一堆中取
for(int i = b - 1;i >= 0;--i){
if(validate(a,i))printf("%d %d\n",a,i);
}
}
}
return 0;
}
}
标签:博弈,int,return,两堆,printf,佐夫,validate,include 来源: https://blog.csdn.net/softwareX4/article/details/98519248
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。