zoukankan      html  css  js  c++  java
  • Codechef A Game With a Sheet of Paper

    Discription

    Yuuko and Nagi like to play the following game:

    Initially they take a checkered sheet of paper of the size of N x M cells. Then, one cell, let's call this cell (XY) is marked. Then, they take the moves alternately. A move consists of making a long horizontal or vertical cut. This cut should coincide with one of the lines that divide the sheet into cells. Then, a part that doesn't contain a marked cell is thrown away and another player takes her turn. A player who is unable to make a turn because after the opponent's turn the dimensions of the sheet became equal to 1 x 1 loses. Yuuko plays first.

    Yuuko and Nagi have played a lot of games together so now they both know the optimal strategy and always use it. Today girls are going to play a game on a N x M cells sheet of paper, but they haven't yet decided, what is the cell (XY) to be marked. Yuuko is interested, in how many ways it's possible to choose this cell so the she can become a winner, regardless of Nagi's moves.

    Input

    The first line of input consists of an integer T - the number of test cases. Then, Tlines describing the test cases follow. The i-th such line contains two integers Nand M, separated by a single space.

    Output

    For each test case, output a single line containing the number of ways to choose the marked cell in order to ensure Yuuko's win.

    Example

    Input:
    2
    5 8
    6 7
    
    Output:
    40
    42
    

    Scoring

    T = 100, 1 <= NM <= 10 : 25 points.

    T = 100, 1 <= NM <= 1000 : 36 points.

    T = 100, 1 <= NM <= 106 : 39 points.

    至于中文题面。。。

    Mandarin Chinese 

    假设我们选了(x,y)点,那么它上面有x-1行,下面有n-x行,左边有y-1列,右边有m-y列。

    而每次切割相当于让这四个量中的一个减小任意(但必须保证操作后是非负数)

    这不就是Nim游戏吗???

    但是光看出这个还不行,因为题目还要快速的算方案数。

    先手必胜的情况下SG函数的Nim和是不为0的,这个不太好算,我们不妨算一下后手必胜的方案,再用总方案减去这个就是答案(总方案数显然是n*m)

    然后发现其实并不是完全意义上的4堆石子,因为行的两堆和列的两堆是有相互限制的。

    我们要让4堆石子的SG函数的Nim和为0,那就让行的Nim和和列的Nim和相等即可,那么我们就用a[i]记录行的Nim和==i的有多少组,

    然后找列的时候累加a[i^(m-1-i)]即可。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cstring>
    #define ll long long
    #define maxn 1000005
    using namespace std;
    ll tot,n,m;
    int T,a[maxn];
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%lld%lld",&n,&m);
            tot=n*m;
            n--,m--;
            
            if(n>m) swap(n,m);
            for(int i=0;i<=n;i++) a[i^(n-i)]++;
            for(int i=0;i<=m;i++) tot-=(ll)a[i^(m-i)];
            printf("%lld
    ",tot);
            
            if(T) memset(a,0,sizeof(a));
        }
        
        return 0;
    }
  • 相关阅读:
    win 8升级win8.1的几个问题
    使用ghost硬盘对拷备份系统
    在odl中怎样实现rpc
    ASP.NET常见内置对象(一)
    [Xcode 实际操作]六、媒体与动画-(12)检测UIView动画的结束事件:反转动画并缩小至不可见状态
    [Xcode 实际操作]六、媒体与动画-(11)UIView视图卷曲动画的制作
    [Xcode 实际操作]六、媒体与动画-(10)UIView视图翻转动的画制作
    [Xcode 实际操作]六、媒体与动画-(9)使用CATransaction Push制作入场动画
    [Xcode 实际操作]六、媒体与动画-(8)使用CATransaction Reveal制作渐显动画
    [Xcode 实际操作]六、媒体与动画-(7)遍历系统提供的所有滤镜
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8361454.html
Copyright © 2011-2022 走看看