【贪心】取火柴游戏

【贪心】取火柴游戏

题目描述

输入k及k个整数n1,n2,…,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni;接着便是你和计算机取火柴棒的对弈游戏。取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不允许跨堆取,也不允许不取。

谁取走最后一根火柴为胜利者。

例如:k=2,n1=n2=2,A代表你,P代表计算机,若决定A先取:

A:(2,2)→(1,2)    {从一堆中取一根}

P:(1,2)→(1,1)    {从另一堆中取一根}

A:(1,1)→(1,0)

P:(1,0)→ (0,0)    {P胜利}

如果决定A后取:

P:(2,2)→(2,0)

A:(2,0)→ 0,0)    {A胜利}

又如k=3,n1=1,n2=2,n3=3,A决定后取:

P:(1,2,3)→(0,2,3)

A:(0,2,3)→(0,2,2)

A已将游戏归结为(2,2)的情况,不管P如何取A都必胜。

编一个程序,在给出初始状态之后,判断是先取必胜还是先取必败,如果是先取必胜,请输

出第一次该如何取。如果是先取必败,则输出“lose”。

输入

输入k及k个整数n1,n2,…,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni;

输出

判断是先取必胜还是先取必败,如果是先取必胜,请输出第一次该如何取。如果是先取必败,则输出“lose”。

样例输入

3
3 6 9

样例输出

4 3
3 6 5 分析:先求出所有元素的异或m,不为0,则必胜;m依次异或得到的值比这个元素小,则变成这个值即可;代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include <ext/rope>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define vi vector<int>
#define pii pair<int,int>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
const int maxn=1e5+10;
const int dis[4][2]={{0,1},{-1,0},{0,-1},{1,0}};
using namespace std;
using namespace __gnu_cxx;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
int n,m,a[maxn];
int main()
{
    int i,j,k,t;
    scanf("%d",&n);
    rep(i,0,n-1)scanf("%d",&a[i]),m^=a[i];
    if(!m)puts("lose");
    else
    {
        rep(i,0,n-1)
            if((m^a[i])<a[i]){
                printf("%d %d\n",a[i]-(m^a[i]),i+1);a[i]=m^a[i];
                break;
            }
        rep(i,0,n-1)printf("%d ",a[i]);
        printf("\n");
    }
    //system ("pause");
    return 0;
}
时间: 2024-10-11 01:23:59

【贪心】取火柴游戏的相关文章

【博弈论】取火柴游戏

取火柴游戏 时间限制: 1 Sec  内存限制: 128 MB 题目描述 输入k及k个整数n1,n2,…,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni:接着便是你和计算机取火柴棒的对弈游戏.取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不允许跨堆取,也不允许不取. 谁取走最后一根火柴为胜利者. 例如:k=2,n1=n2=2,A代表你,P代表计算机,若决定A先取: A:(2,2)→(1,2)    {从一堆中取一根} P:(1,2)→(1,1)    {从另一堆中取一根}

P1247 取火柴游戏

题目描述 输入k及k个整数n1,n2,…,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni:接着便是你和计算机取火柴棒的对弈游戏.取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不允许跨堆取,也不允许不取. 谁取走最后一根火柴为胜利者. 例如:k=2,n1=n2=2,A代表你,P代表计算机,若决定A先取: A:(2,2)→(1,2) {从一堆中取一根} P:(1,2)→(1,1) {从另一堆中取一根} A:(1,1)→(1,0) P:(1,0)→ (0,0) {P胜利} 如果

P1247 取火柴游戏 (奇异局势)

题目链接 题目描述 输入k及k个整数n1,n2,…,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni:接着便是你和计算机取火柴棒的对弈游戏.取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不允许跨堆取,也不允许不取. 谁取走最后一根火柴为胜利者. 编一个程序,在给出初始状态之后,判断是先取必胜还是先取必败,如果是先取必胜,请输出第一次该如何取.如果是先取必败,则输出“lose”. 输入格式 第一行,一个正整数k 第二行,k个整数n1,n2,…,nk 输出格式 如果是先取必胜,

洛谷P1247 取火柴游戏 数学题 博弈论

这题就是NIM取石子游戏,但是NIM取石子方案并不是单一的,而是有多种方案的,现在让我们求字典序最小的方案,其实还是简单的,作为先手,如果是必胜局面,那我们肯定第一步把所有子异或和变为零 ,这样对于对方,这就是一个必败局面了 2.那我们来考虑怎么把局面变成必败局面呢,换句话说,怎么判断这一堆取不取呢, 假设a[ i ]不取他们的异或值为 y ,那么如果我们把a[ i ]变成 y 那么 y^y=0 就必胜了那就只要判断 if a[ i ]>=y 就可知在这一位上改变可不可行了,要字典序最小那就i从

P1247 取火柴游戏(异或理论)

https://www.luogu.com.cn/problem/P1247 #include <bits/stdc++.h> using namespace std; #define int long long const int maxn = 5e5 + 5; int n; int a[maxn]; signed main(){ //freopen("in","r",stdin); ios::sync_with_stdio(0); cin >&

【贪心】取数游戏

问题 N: [贪心]取数游戏 时间限制: 1 Sec  内存限制: 64 MB提交: 51  解决: 31[提交][状态][讨论版] 题目描述 给出2n(n≤100)个自然数(小于等于30000).将这2n个自然数排成一列,游戏双方A和B从中取数,只允许从两端取数.A先取,然后双方轮流取数.取完时,谁取得数字总和最大为取胜方:若双方和相等,属B胜.试问A方是否有必胜策略? 输入 共2行,第1行一个整数n:第2行有2*n个自然数. 输出 只有1行,若A有必胜策略,则输出“YES”,否则输出“NO”

【贪心】取数游戏(UPCOJ3595)

取数游戏 时间限制: 1 Sec  内存限制: 64 MB 题目描述 给出2n(n≤100)个自然数(小于等于30000).将这2n个自然数排成一列,游戏双方A和B从中取数,只允许从两端取数.A先取,然后双方轮流取数.取完时,谁取得数字总和最大为取胜方:若双方和相等,属B胜.试问A方是否有必胜策略? 输入 共2行,第1行一个整数n:第2行有2*n个自然数. 输出 只有1行,若A有必胜策略,则输出"YES",否则输出"NO". 样例输入 4 7 9 3 6 4 2 5

取火柴-博弈论

取火柴 (10分)C时间限制:3000 毫秒 | C内存限制:3000 Kb题目内容: 有n个火柴棍,两个游戏玩家a和b轮流取,规则是第一次取的人最少取1根,最多取n-1根,随后每人最多只能取对方上一次取的数目 的2倍,最少取1根.谁取到最后一根为胜者.试问先取的人是赢还是输. 输入描述n输出描述1表示胜,0表示输输入样例3输出样例0 解析:说白了,就是每个人只能取1或者2.(双方都不想因为自己而让对方的选择余地变大) #include<iostream> using namespace st

[数学故事]火柴游戏

一个最普通的火柴游戏就是两人一起玩,先置若干支火柴於桌上,两人轮流取,每次所取的数目可先作一些限制,规定取走最后一根火柴者获胜. 规则一:若限制每次所取的火柴数目最少一根,最多三根,则如何玩才可致胜? 例如:桌面上有 n=15 根火柴,甲.乙两人轮流取,甲先取,则甲应如何取才能致胜? 为了要取得最后一根,甲必须最后留下零根火柴给乙,故在最后一步之前的轮取中,甲不能留下1根或2根或3根,否则乙就可以全部取走而获胜.如果留下4根,则乙不能全取,则不管乙取几根(1或2或3),甲必能取得所有剩下的火柴而