2016多校联合训练赛 第六场1003 A Simple Nim hdu 5795

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795
题意:给出n堆石子,双方轮流从从一堆中拿出至少一个棋子或把其中一堆分成三堆非空的石子堆,问先手是否有必胜策略。
想法:明显是Nim游戏类型,那么我们需要考虑给出的分石子这步特殊的操作。之前在hihoCoder上面做过分成两堆的题目,当时是找的规律,所以比赛时就直接打了个表。发现只有在被8整除时或者被8除余7时,SG值才会有变化。那很直接的每步对应的异或下SG值就好了。
代码如下:

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

const int MAXN = 100 + 10;
int sg[MAXN];
bool vis[MAXN];

int main(){
    /*
    freopen("3.out", "w", stdout);
    sg[0] = 0;
    for(int i = 1; i < MAXN; ++i){
        memset(vis, false, sizeof(vis));
        for(int j = 0; j < i; ++j){
            vis[sg[j]] = true;  
        }
        for(int j = 1; j <= i; ++j){
            for(int k = 1; k <= i; ++k){
                for(int l = 1; l <= i; ++l){    
                    if(k + j + l == i){
                        vis[sg[j] ^ sg[k] ^ sg[l]] = true;
                    }
                }
            }
        }
        for(int j = 0; j < 300; ++j){
            if(!vis[j]){
                sg[i] = j;
                break;
            }
        }
    }

    for(int i = 0 ; i < MAXN; ++i){
        if(sg[i] != i){
            printf("sg[%d] = %d\n", i, sg[i]);  
        }
    }*/
    int cas;
    scanf("%d", &cas);
    while(cas--){
        int n;
        scanf("%d", &n);
        int ans = 0, x;
        for(int i = 0; i < n; ++i){
            scanf("%d", &x);
            if(x % 8 == 0){
                ans ^= x - 1;   
            }else if(x % 8 == 7){
                ans ^= x + 1;   
            }else{
                ans ^= x;   
            }   
        }
        if(!ans){
            puts("Second player wins.");
        }else{
            puts("First player wins."); 
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Nim 语言中编写多线程程序,可以使用 Nim 标准库中提供的 `threading` 模块。下面是一个简单的示例程序: ```nim import threading var counter = 0 var lock = newMutex() proc worker() = for i in 0..999: lock.acquire() counter += 1 lock.release() var threads = newSeq[Thread](4) for i in 0..<threads.len: threads[i] = newThread(worker) for i in 0..<threads.len: threads[i].join() echo "Counter: ", counter ``` 这个程序创建了一个计数器 `counter`,然后启动了 4 个线程来同时增加计数器的值。每个线程都会调用 `worker` 这个过程,其中 `lock.acquire()` 和 `lock.release()` 分别表示加锁和解锁,以保证多个线程不会同时访问和修改 `counter` 变量。 最后,主线程会等待所有子线程执行完毕后,输出计数器的最终值。 ### 回答2: Nim是一种多范式编程语言,它可以用于编写多线程程序。下面是使用Nim语言编写多线程程序的一般步骤: 1. 导入Nim中的`threadpool`模块,该模块提供了多线程编程所需的函数和类型。 2. 定义一个过程或方法来执行线程的任务。该过程或方法将在多个线程中并发执行。 3. 创建一个线程池对象,并通过调用`newThreadPool`函数来指定希望创建的线程数量。 4. 使用线程池对象的`schedule`函数来调度任务执行。可以使用该函数的`spawn`参数来指定要执行的任务,以及可选的`callback`参数来处理任务执行后的结果。 5. 如果需要等待所有线程完成任务,可以使用线程池对象的`join`函数来等待所有任务完成。 6. 最后,可以释放线程池对象的内存,以避免内存泄漏。可以通过将线程池对象分配给一个可选的null值来实现。 以下是一个使用Nim编写的简单示例,展示了如何创建和使用线程池进行多线程编程: ```nim import threadpool proc task() = # 执行线程的任务 echo "Hello from task" var pool = newThreadPool(2) # 创建一个包含2个线程的线程池 pool.schedule(spawn task) # 调度任务执行 pool.schedule(spawn task) # 调度更多任务执行 pool.join() # 等待所有任务完成 pool = null # 释放线程池内存 ``` 以上是使用Nim语言编写多线程程序的一般步骤和示例代码。要注意的是,在编写多线程程序时,需要注意线程间的同步和共享资源的管理,以避免潜在的竞态条件和线程安全问题。 ### 回答3: Nim语言是一种多范式编程语言,支持多线程编程。下面我将分享一些关于在Nim语言中编写多线程程序的基本思路和方法。 首先,你需要在程序中引入`threadpool`模块,该模块提供了多线程支持的相关功能。该模块提供了一个`ThreadPool`类型,可以用于创建线程池对象。 创建线程池对象后,你可以通过调用`submit`函数向线程池提交任务。这个函数接收一个闭包或过程作为参数,然后将其放入任务队列等待被执行。例如,你可以编写如下代码: ```nim import threadpool proc myTask() = echo "This is a task executed in a thread." var pool = newThreadPool(4) pool.submit(myTask) ``` 在上述代码中,`myTask`过程会被放入线程池中,然后在线程池中的一个线程中执行。 此外,你可以使用`result`函数获取任务的结果。如果任务尚未完成,它会阻塞线程直到任务完成并返回结果。例如: ```nim import threadpool proc myTask(): int = return 42 var pool = newThreadPool(4) var task = pool.submit(myTask) var result = task.result() echo "The result is: ", result ``` 上述代码中,`myTask`过程返回整数值 42。通过调用`result`函数,线程将被阻塞直到任务完成,并获取到任务的结果。 需要注意的是,多线程编程存在一些潜在的隐患,例如多线程访问共享数据可能导致数据竞争。因此,在编写多线程程序时,你需要仔细考虑并充分测试你的代码以确保线程安全。 总结起来,编写多线程程序时,请使用`threadpool`模块创建线程池对象,并利用其提供的函数向线程池提交任务。同时,注意处理线程安全的问题。希望这些信息能帮助到你编写多线程程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值