zoukankan      html  css  js  c++  java
  • [USACO11OPEN]奶牛跳棋Cow Checkers(博弈论)

    题目描述

    One day, Bessie decides to challenge Farmer John to a game of 'Cow Checkers'. The game is played on an M*N (1 <= M <= 1,000,000; 1 <= N <= 1,000,000) checkerboard that initially contains a single checker piece on the checkboard square coordinates (X, Y) (0 <= X < M; 0 <= Y < N). The bottom leftmost square of the checkerboard has

    coordinates (0, 0), and the top rightmost square has coordinates (M-1, N-1). Bessie always moves first, and then the two players alternate turns. Each turn comprises one of three types of moves:

    1) Move the checker piece to any square on the same row to the left of its current position.

    2) Move the checker piece to any square on the same column below its current position.

    3) Move the checker piece to any spot k squares below and k squares to the left of the current square (where k is any positive integer such that this new spot is still on the checkerboard).

    The first player unable to make a move (i.e., because the checker is at (0, 0)) loses. Given that Bessie always goes first, determine who will win the game if both play optimally.

    Play and report the winner for T games (1 <= T <= 1,000) reading in a new X,Y starting value for each new game.

    有一天,Bessie准备玩一个叫做奶牛跳棋的游戏,来挑战Farmer John。

    这个游戏的棋盘大小为 M*N (1 <= M <= 1,000,000; 1 <= N <= 1,000,000) 。最初棋盘上只有一个棋子在(x,y),棋盘的左下角坐标是(0,0),右上角的坐标是(M-1,N-1)。

    每次游戏Bessie都是第一个开始,之后两个人轮流。

    每次下棋的时候都有三种走法:

    1.向左走任意步

    2.向下走任意步

    3.向左走k步然后向下走k步(k可随便取值,只要不走出棋盘)

    先走到(0,0)的人就算输。

    游戏共有T次,每次都会给出一个新的坐标(x,y),请输出每一轮赢家的名字。

    输入输出格式

    输入格式:

    * Line 1: Two space-separated integers: M and N

    * Line 2: A single integer: T

    * Lines 3..T+2: Two space-separated integers: X and Y

    第一行:M N

    第二行:T

    第三行到第T+2行:这一轮的X Y

    输出格式:

    * Lines 1..T: Should contain either 'Farmer John' or 'Bessie' depending on who wins each game.

    共T行,每一行输出那一轮的赢家

    思路;

    这是一道标准的博弈论(不过好难想啊!!)

    横坐标和纵坐标可以抽象为两堆石子

    向下走任意步=拿出A堆任意个石子,向左走任意步=拿出B堆任意个石子

    向左走和向下走相同的任意步=拿出A堆和B堆个数相等的任意个石子

    这就抽象成了一个威佐夫博弈的模型

    套用公式算一下是否是奇异局面就行(不知道什么是威佐夫博弈的请出门左转百度,讲的很详细)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define rii register int i
    using namespace std;
    int x,y,n,t,m;
    int check(int l,int k)
    {
        if(l>k)
        {
            swap(l,k);
        }
        int wzf=(double)((k-l)*(sqrt(5)+1)/2);
        if(wzf==l)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        scanf("%d",&t);
        for(rii=1;i<=t;i++)
        {
            scanf("%d%d",&x,&y);
            int pd=check(x,y);
            if(pd==0)
            {
                cout<<"Bessie"<<endl;
            }
            else
            {
                cout<<"Farmer John"<<endl;
            }
        }
    }
  • 相关阅读:
    24、合并两个有序链表
    23、反转链表
    22、删除链表的倒数第N个节点
    21、删除链表中的节点
    18、实现strStr()
    17、字符串转换整数 (atoi)
    15、有效的字母异位词
    16、验证回文字符串
    14、字符串中的第一个唯一字符
    mybatis入门(七)----延迟加载
  • 原文地址:https://www.cnblogs.com/ztz11/p/9330050.html
Copyright © 2011-2022 走看看