• 【CF39E】【博弈论】What Has Dirichlet Got to Do with That?


    Description

    You all know the Dirichlet principle, the point of which is that if n boxes have no less than n + 1 items, that leads to the existence of a box in which there are at least two items.

    Having heard of that principle, but having not mastered the technique of logical thinking, 8 year olds Stas and Masha invented a game. There are a different boxes and b different items, and each turn a player can either add a new box or a new item. The player, after whose turn the number of ways of putting b items into a boxes becomes no less then a certain given number n, loses. All the boxes and items are considered to be different. Boxes may remain empty.

    Who loses if both players play optimally and Stas's turn is first?

    Input

    The only input line has three integers a, b, n (1 ≤ a ≤ 10000, 1 ≤ b ≤ 30, 2 ≤ n ≤ 109) — the initial number of the boxes, the number of the items and the number which constrains the number of ways, respectively. Guaranteed that the initial number of ways is strictly less than n.

    Output

    Output "Stas" if Masha wins. Output "Masha" if Stas wins. In case of a draw, output "Missing".

    Sample Input

    Input
    2 2 10
    Output
    Masha
    Input
    5 5 16808
    Output
    Masha
    Input
    3 1 4
    Output
    Stas
    Input
    1 4 10
    Output
    Missing

    Hint

    In the second example the initial number of ways is equal to 3125.

    • If Stas increases the number of boxes, he will lose, as Masha may increase the number of boxes once more during her turn. After that any Stas's move will lead to defeat.
    • But if Stas increases the number of items, then any Masha's move will be losing.

    Source

    【分析】
    还不错的题目,跟普通的题目有区别的是有平局的情况。
    需要特判一下。
    如a = 1的时候,如果两个人都在b上面操作,就不会有结果。
    所以模拟一下b的增加然后判断增加1的时候的胜败态就行了。
    还有b = 1时同理。
    还有就是a b 同时为1的时候
      1 /*
      2 酒逢知己千杯少,话不投机半句多。
      3 遥知湖上一樽酒,能忆天涯万里人。
      4 */
      5 
      6 #include <set>
      7 #include <map>
      8 #include <cmath>
      9 #include <cstdio>
     10 #include <vector>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <iostream>
     14 #include <algorithm>
     15 #define LOCAL
     16 const int MAXL = 20;
     17 const long long MOD = 1000000007;
     18 const int MAXK = 10000 + 10;
     19 const int MAXN = 35000 + 10;
     20 const int MAXM = 35;
     21 using namespace std;
     22 typedef long long LL;
     23 int a , b , n , sg[MAXN][MAXM];
     24 
     25 LL pow(int a, int b){
     26    if (b == 0) return 1ll;
     27    if (b == 1) return (LL)a;
     28    LL tmp = pow(a, b / 2);
     29    if (b % 2 == 0) return tmp * tmp;
     30    else return (LL)tmp * tmp * (LL)a;
     31 }
     32 int dfs (int a , int b) {
     33     if (sg[a][b] >= 0) return sg[a][b];
     34     if (pow(a, b) >= (LL)n) {
     35         return sg[a][b] = 1;
     36     }
     37     int Ans = 0;
     38     Ans |= !dfs(a + 1 , b);//只要有一个是1就能够获胜 
     39     Ans |= !dfs(a , b + 1);
     40     return sg[a][b] = Ans;
     41 }
     42 int work_2(int a){
     43     int b = 1, turn = 0;
     44     int up = (int)sqrt((double)n - 0.0000001);//处理上界 
     45     while (a <= up){
     46           if (sg[a][b + 1] == 0) return (turn == 0);
     47           a++;
     48           turn = turn ^ 1;
     49     }
     50     //剩下的就是判断奇偶性,看谁先到 
     51     turn = (turn + (n - 1 - a)) % 2;
     52     return turn;
     53 }
     54 int work_1(int b){
     55     int a = 1;
     56     if (pow(a, b) >= n) return 0;
     57     else {
     58          int turn = 0;
     59          for (; !(pow(2, b) >= n); b++){
     60              if (sg[a + 1][b] == 0){
     61                 if (turn == 0) return 1;
     62                 else return -1;
     63              }
     64              turn ^= 1; 
     65          }
     66          return 0;
     67     }
     68 } 
     69 
     70 int main () {
     71     
     72     memset(sg , -1 , sizeof (sg));
     73     scanf("%d%d%d", &a, &b, &n);
     74     if (pow(a, b) >= n) {
     75         puts ("Masha");
     76         return 0;
     77     }
     78     dfs(2, 2);
     79     if (a != 1 && b != 1){
     80        if (sg[a][b] != 0) printf("Masha");
     81        else printf("Stas");
     82        return 0;
     83     }
     84     
     85     if (a == 1 && b == 1){
     86        int c = work_1(b + 1);
     87        int d = work_2(a + 1);
     88        if (c < 0 || d == 0) printf("Masha");
     89        else if (c == 0) printf("Missing");
     90        else printf("Stas");
     91     }else if (b == 1){
     92           if (work_2(a) != 0) printf("Masha");
     93           else printf("Stas");
     94     }else if (a == 1){
     95           int tmp = work_1(b);
     96           if (tmp == 0) printf("Missing");
     97           else if (tmp == 1) printf("Masha");
     98           else printf("Stas");
     99     }
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    学习进度笔记16
    《软件架构师的12项修炼》阅读笔记1
    学习进度笔记15
    CSS前端性能优化
    多行文本溢出,显示省略号
    VIM编辑器使用
    iOS 兼容性处理
    javascript 对象
    JS滚轮事件(mousewheel/DOMMouseScroll)了解
    MarkDown编辑器基础使用教程
  • 原文地址:https://www.cnblogs.com/hoskey/p/4357716.html
Copyright © 2020-2023  润新知