1 2 5 8 4 7 2 2 0 0
0 1 4 7 3 5 0 1 0 0 1 2
题目类型:博弈
题意:中文题意,不解释了
题解:对于一个状态(a,b),先对a,b大小判断,让a<b。设置一个变量k为a,b差值(k=b-a),然后判断
a == k*(1+sqrt(5.0))/2.0相等,则表示(a,b)为奇异态。
我用的是枚举的方法去做题,对于奇异点,直接输出0即可,对于非奇异点,怎么做才能做到让其变成奇异点,有两种方法(当然这两种方法不一定都行),第一,从两堆中取相等的使其变成奇异点,第二,从某一堆中取相等的变成奇异点。而题目顺序也就是要我们按照这两种方法顺序来输出做法。
虽说这种题目属于模版题,好歹花了我一晚上的时间啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 啊 啊啊啊啊 啊
附上详细注释代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int main() { int m,n,i,k,k1,k2,k3,temp; double t=(1+sqrt(5.0))/2.0; //威佐夫博弈公式公共部分 while(~scanf("%d%d",&m,&n)&&m+n) { if(m>n) //交换 { temp=m; m=n; n=temp; } k=n-m; //m相当于a[k],n相当于b[k],则根据k来判定是否为奇异局势 if(int(k*t)==m) //如果a[i]=k*t说明是奇异局势 printf("0\n"); else { printf("1\n"); for(i=1;i<=m;i++) //找相同的 { k1=m-i;k2=n-i; if(int((k2-k1)*t)==k1) //强制转换 printf("%d %d\n",k1,k2); } for(i=n;i>=0;i--) //为什么从较多的那一堆去拿而不从较少的拿,因为从较少的拿会有重叠的一部分 { //而这一部分从较多的那一堆拿就已经可以包含了 int a=m; //这个地方一定要注意要重新设置变量 int b=i; if(a>b) { temp=a; a=b; b=temp; } k1=b-a; if(int(k1*t)==a) //如果相等,这样从某一堆去拿 printf("%d %d\n",a,b); } } } return 0; }
原文地址:http://blog.csdn.net/magic_spongebob/article/details/44752763