zoukankan      html  css  js  c++  java
  • BZOJ 3105:[cqoi2013]新Nim游戏

    BZOJ 3105:[cqoi2013]新Nim游戏

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3105

    题目大意:在传统的Nim取石子游戏中做了改变:两人刚开始可以取走任意堆石子(不包括全部)后进行传统游戏,问先手能否必胜,若必胜求出刚开始最少取多少石子。

    线性基

    传统Nim游戏先手必胜的前提条件为所有石子堆的异或和不为零.

    故若欲使新Nim游戏先手必胜,则需保证先手刚开始取完后剩下的元素线性无关.

    而问最少取多少石子,只需将原数列降序排序,贪心构造极大线性无关组.

    代码如下:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #define MAX_BASE 30
     4 using namespace std;
     5 typedef long long ll;
     6 ll n,a[105],b[105];
     7 bool cmp(ll a,ll b){
     8     return a>b;
     9 }
    10 ll cal(){
    11     ll ans=0;
    12     for(int i=0;i<n;++i){
    13         ll t=a[i];
    14         bool f=0;
    15         for(int j=MAX_BASE;j>=0;--j){
    16             if(a[i]>>j&1){
    17                 if(b[j])a[i]^=b[j];
    18                 else{
    19                     b[j]=a[i];
    20                     f=1;
    21                     for(int k=j-1;k>=0;--k)if(b[k]&&(b[j]>>k&1))b[j]^=b[k];
    22                     for(int k=j+1;k<=MAX_BASE;++k)if(b[k]>>j&1)b[k]^=b[j];
    23                     break;
    24                 }
    25             }
    26         }
    27         if(f)ans+=t;
    28     }
    29     return ans;
    30 }
    31 int main(void){
    32     ll sum=0,ans;
    33     scanf("%lld",&n);
    34     for(int i=0;i<n;++i){
    35         scanf("%lld",&a[i]);
    36         sum+=a[i];
    37     }
    38     sort(a,a+n,cmp);
    39     ans=cal();
    40 printf("%lld ",sum-ans); 41 }
  • 相关阅读:
    CSRF跨站请求伪造
    FineReport 导出汉字乱码
    Java 程序中中文没有乱码,存入数据库后中文乱码问题
    分析函数
    Redis的持久化与主从复制
    分布式Redis的使用
    redis的介绍和安装
    Solr后台管理及SolrJ的使用
    Solr总结
    bootstrap 点击回到顶部 超简单
  • 原文地址:https://www.cnblogs.com/barrier/p/6878672.html
Copyright © 2011-2022 走看看