51nod1714(简单的博弈,SG函数)

本文分享了一道关于博弈论的编程题目解题过程,通过直接暴力计算SG函数值的方法,在短时间内解决了问题。文章提供了完整的代码示例,并展示了如何利用预计算的SG函数值来快速判断游戏结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1714

上51nod突然发现很久以前有个题没有过,发现是博弈,要求SG函数,但是抓耳挠腮也没想出来怎么在时限里求,于是看了看解题报告,说是用一种不算暴力的暴力,还是不懂,还去问了q巨(q巨对我说直接暴力,跑的飞快),我跑了一下,几秒钟没跑出来就又怯生生地去问q巨,q巨说一分钟不到就可以跑出来了啊(晕,这算不算暴力的暴力吗,可能是我眼界窄吧),于是怒暴力打表,问题迎刃而解。

//
//  main.cpp
//  1714
//
//  Created by 黄宇凡 on 8/1/16.
//  Copyright © 2016 黄宇凡. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

long long sg[65] = {0,
    1,
    2,
    4,
    8,
    16,
    32,
    64,
    128,
    255,
    256,
    512,
    1024,
    2048,
    3855,
    4096,
    8192,
    13107,
    16384,
    21845,
    27306,
    32768,
    38506,
    65536,
    71576,
    92115,
    101470,
    131072,
    138406,
    172589,
    240014,
    262144,
    272069,
    380556,
    524288,
    536169,
    679601,
    847140,
    1048576,
    1072054,
    1258879,
    1397519,
    2005450,
    2097152,
    2121415,
    2496892,
    2738813,
    3993667,
    4194304,
    4241896,
    4617503,
    5821704,
    7559873,
    8388608,
    8439273,
    8861366,
    11119275,
    11973252,
    13280789,
    16777216,
    16844349,
    17102035,
    19984054,
    21979742,
    23734709
};
//int vis[100000000];

//void init(){
//    sg[0] = 0;
//    for(int i = 1;i <= 64;i++){
//        for(int j1 = 0;j1 < i;j1++){
//            for(int j2 = j1;j2 < i;j2++){
//                for(int j3 = j2;j3 < i;j3++){
//                    for(int j4 = j3;j4 < i;j4++){
//                        for(int j5 = j4;j5 < i;j5++){
//                            for(int j6 = j5;j6 < i;j6++){
//                                for(int j7 = j6;j7 < i;j7++){
//                                    long long tmp = sg[j1] ^ sg[j2] ^ sg[j3] ^ sg[j4] ^ sg[j5] ^ sg[j6] ^ sg[j7];
//                                    vis[tmp] = i;
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        for(int j = 0;j < 30000000;j++){
//            if(vis[j] != i) {sg[i] = j;break;}
//        }
//    }
//}

int main(int argc, const char * argv[]) {
    //init();
//    for(int i = 0;i <= 64;i++){
//        cout << sg[i] << endl;
//    }
    int n;
    cin >> n;
    unsigned long long x;
    long long ans = 0;
    for(int i = 1;i <= n;i++){
        cin >> x;
        int sum = 0;
        while(x > 0){
            if(x & 1) sum++;
            x >>= 1;
        }
        ans ^= sg[sum];
    }
    if(ans == 0) printf("L\n");
    else printf("B\n");
    return 0;
}
### 关于51Nod平台上编号为1020的问题详情与解答 #### 问题描述 在51Nod平台上的第1020号问题是关于计算两个大整数相加的结果[^1]。给定两个正整数A和B,长度不超过10^6位,要求编写程序来求解这两个数的和。 #### 输入格式说明 输入数据由多组测试案例组成;每组测试案例占两行,分别表示要相加的大整数A和B。对于每一组测试案例,应当单独输出一行结果,即A+B的值。 #### 解决方案概述 解决此问题的关键在于处理超大数据类型的运算,在大多数编程语言中内置的数据类型无法直接支持如此大规模数值的操作。因此,可以采用字符串的方式来存储这些大整数,并实现逐位相加逻辑,同时考虑进位情况。 下面是一个Python版本的具体实现方法: ```python def add_large_numbers(a: str, b: str) -> str: # Reverse strings to make addition easier from least significant digit a = a[::-1] b = b[::-1] carry = 0 result = [] max_length = max(len(a), len(b)) for i in range(max_length): digit_a = int(a[i]) if i < len(a) else 0 digit_b = int(b[i]) if i < len(b) else 0 total = digit_a + digit_b + carry carry = total // 10 current_digit = total % 10 result.append(str(current_digit)) if carry != 0: result.append(str(carry)) return ''.join(reversed(result)) if __name__ == "__main__": while True: try: num1 = input().strip() num2 = input().strip() print(add_large_numbers(num1, num2)) except EOFError: break ``` 该代码片段定义了一个函数`add_large_numbers`用于接收两个作为参数传入的大整数(形式上为字符串),并返回它们之和同样作为一个字符串。通过反转输入字符串使得最低有效位位于索引位置0处从而简化了按位累加的过程。最后再将得到的结果列表反向拼接成最终答案输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值