zoukankan      html  css  js  c++  java
  • jzoj【NOIP2011模拟10.31】T1游戏

    T1游戏

    Description

    Alice和Bob在玩一个游戏,游戏是在一个N*N的矩阵上进行的,每个格子上都有

    一个正整数。当轮到Alice/Bob时,他/她可以选择最后一列或最后一行,并将其删除,但

    必须保证选择的这一行或这一列所有数的和为偶数。如果他/她不能删除最后一行或最后一

    列,那么他/她就输了。两人都用最优策略来玩游戏,Alice先手,问Alice是否可以必胜?

    Input

    第一行:T,表示数据组数

    对于每组数据的第一行:N

    接下来N行,每行N个数,描述这个矩阵

    Output

    如果Alice必胜输出W,否则输出L

    一道dp题,
    我们可以从右上角开始,逐一枚举{当最终点落在(i,j)上的输赢情况},
    没有平局,所以只需要考虑是否为偶数和是否必胜,
    于是就可以进行判断,
    如果  当前列为偶数,且去除此列后的最右下角的点必输,那么这个点可以标记做必胜,
    同理 当前行为偶数,同样判断取出后的情况即可。
    用前缀和(sum)来优化。
    当 sum[i][j]-sum[i][j-1])%2==0  dp[i][i]=max(dp[i][j-1]^1,dp[i][j]);
    当 sum[i][j]-sum[i-1][j])%2==0  dp[i][i]=max(dp[i-1][j-1]^1,dp[i][j]);
    于是
    #include<bits/stdc++.h>
    using namespace std;
    bool dp[1005][1005];
    int t,f[1005][1005],n;
    int main()
    {
        cin>>t;
        while(t--)
        {
            memset(f,0,sizeof(f));
            memset(dp,0,sizeof(dp));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&f[i][j]);
                f[i][j]=f[i][j]+f[i-1][j]+f[i][j-1]-f[i-1][j-1]; 
            }
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(dp[i][j-1]==false)
                if((f[i][j]-f[i][j-1])%2==0)
                {
                    dp[i][j]=1;continue;
                }
                if(dp[i-1][j]==false)
                if((f[i][j]-f[i-1][j])%2==0)
                {
                    dp[i][j]=1;continue;
                } 
            }
            if(dp[n][n])
            printf("W
    ");
            else
            printf("L
    ");
        }
    }
     
  • 相关阅读:
    Spring 源码学习
    Feign Client 原理和使用
    算法基础:排序算法看这一篇就够了
    Spring 源码学习2
    Spring 源码学习
    最优包裹组合-贪心算法
    @Transactional 事务的底层原理
    Mysql索引扫盲总结
    snowflake原理解析
    分布式ID总结
  • 原文地址:https://www.cnblogs.com/you-xiao-mang-ci/p/11285299.html
Copyright © 2011-2022 走看看