zoukankan      html  css  js  c++  java
  • bzoj 3105: [cqoi2013]新Nim游戏 异或高消 && 拟阵

    3105: [cqoi2013]新Nim游戏

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 535  Solved: 317
    [Submit][Status][Discuss]

    Description

    传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同)。两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴。可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿。拿走最后一根火柴的游戏者胜利。
    本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一样,第二个游戏者也有这样一次机会。从第三个回合(又轮到第一个游戏者)开始,规则和Nim游戏一样。
    如果你先拿,怎样才能保证获胜?如果可以获胜的话,还要让第一回合拿的火柴总数尽量小。
     

    Input

    第一行为整数k。即火柴堆数。第二行包含k个不超过109的正整数,即各堆的火柴个数。
     

    Output

     
    输出第一回合拿的火柴数目的最小值。如果不能保证取胜,输出-1。

    Sample Input

    6
    5 5 6 6 5 5

    Sample Output

    21

    HINT

    k<=100

      才学了拟阵,然后现学现用,居然就发现了这么一道拟阵好题。

      题目简化出来大概是你要在一堆数集中,删除一些数,使得剩下的数不可能组成异或和为0的非空集合,并且使删除的数尽量的小。考虑依次加数,每次加完异或高消一次,如果发现线性相关,那么就不加入这个数,否则加入。这样可以满足删除的数的个数尽量小。

      然而题目中求得是删除的数字的和,怎么办?注意到这道题所说的“子集异或和非0集合”其实就是一个拟阵。【拟阵(E,I)1.空集满足 2.若集合A满足,则A子集满足“子集异或和非0” 3.若card(A)>card(B),存在x属于A,且B+{x}属于I,这个可以用异或高消来理解】所以按照拟阵的标准贪心思路,将读入的数列从大到小排一遍序就ok了。

      发现以前写的异或高消都有bug,整个人都splay起来了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 100000
    typedef long long qword;
    int lst[MAXN];
    inline bool cc(int x,int y)
    {
            for (int i=30;i>=0;i--)
                    if (x&(1<<i))
                            return y&(1<<i);
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int n;
            scanf("%d",&n);
            for (int i=0;i<n;i++)
                    scanf("%d",lst+i);
            sort(lst,lst+n,greater<int>());
            qword ans=0;
            int x,y;
            for (int i=0;i<n;i++)
            {
                    x=lst[i];
                    for (int j=0;j<i;j++)
                    {
                            if (cc(lst[j],lst[i]))
                                    lst[i]^=lst[j];
                    }
                    if (!lst[i])
                            ans+=x;
            }
            printf("%lld
    ",ans);
    }
  • 相关阅读:
    01时间处理--02 指定日期--转成星期
    中文乱码处理
    判断js变量是否定义,
    安卓请求服务器js文件下载到本地,版本号不一致就下载
    a标签href跳转---传值---禁止单引号
    修改mysql配置文件,group_concat设置为最大.默认1024个字节字符串.多条json会超出
    GROUP_CONCAT()多条数据.拼接字符串 最大长度1024
    使用变量判断之前.务必先定义
    多种序列化器-指定类对象
    JsonHelper
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4523329.html
Copyright © 2011-2022 走看看