题目链接:
这题不是普通的 Nim 博弈,我想它应该是另一种博弈吧,于是便推 sg 函数打了个 20*20 的表来看,为了方便看一些,我用颜色作了标记,打表代码如下:
1 #include2 #include 3 #include 4 #include
运行结果如下:
看不出有什么规律,逐百度之,发现原来是威佐夫博奕,最后判定时需要用到黄金分割数什么的,不过是 O(1) 的复杂度,但杭电这道题还要输出第 1 步操作后的结果,也就是还要模拟一下,不知道它的数据量有多少,觉得直接暴力枚举应该会超时吧,便想写个二分,可是写了好久越写越乱,于是干脆试下暴力,竟然秒过了,后台数据估计少得可怜。需要输出的答案最多不会超过 3 组,但为了方便,我还是用 vector 来存下了符合要求的答案:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 const int N = 1000006; 9 const double p = (sqrt(5.0) + 1) / 2;10 11 bool ok(int a, int b) {12 if(a > b) swap(a,b);13 int k = b - a;14 int c = int(k * p);15 return c == a;16 }17 18 int main() {19 int a,b;20 while(~scanf("%d %d",&a,&b),a) {21 if(a > b) swap(a,b);22 if(ok(a,b)) puts("0");23 else {24 puts("1");25 for(int i = 1; i < a; ++i)26 if(ok(a - i, b - i)) printf("%d %d\n", a - i, b - i);27 vector > v;28 for(int i = 1; i < a; ++i)29 if(ok(a - i, b)) v.push_back(make_pair(a - i, b));30 for(int i = 1; i < b; ++i)31 if(ok(a, b - i)) {32 if(a > b - i) v.push_back(make_pair(b - i, a));33 else v.push_back(make_pair(a, b - i));34 }35 sort(v.begin(), v.end());36 int m = unique(v.begin(), v.end()) - v.begin();37 for(int i = 0; i < m; ++i)38 printf("%d %d\n", v[i].first, v[i].second);39 }40 }41 return 0;42 }