首页 > 其他分享 >【题解】P3185 [HNOI2007]分裂游戏

【题解】P3185 [HNOI2007]分裂游戏

时间:2023-04-27 21:12:32浏览次数:55  
标签:P3185 豆子 巧克力 int 题解 -- HNOI2007 SG sg

P3185 [HNOI2007]分裂游戏

题目描述

聪聪和睿睿最近迷上了一款叫做分裂的游戏。

该游戏的规则是: 共有 \(n\) 个瓶子, 标号为 \(0, 1, \ldots, n-1\),第 \(i\) 个瓶子中装有 \(p_i\) 颗巧克力豆,两个人轮流取豆子,每一轮每人选择 \(3\) 个瓶子,标号为 \(i,j,k\), 并要保证 \(i \lt j, j \leq k\),且第 \(i\) 个瓶子中至少要有 \(1\) 颗巧克力豆,随后这个人从第 \(i\) 个瓶子中拿走一颗豆子并在 \(j,k\) 中各放入一粒豆子(\(j\) 可能等于 \(k\)) 。如果轮到某人而他无法按规则取豆子,那么他将输掉比赛。胜利者可以拿走所有的巧克力豆!

两人最后决定由聪聪先取豆子,为了能够得到最终的巧克力豆,聪聪自然希望赢得比赛。他思考了一下,发现在有的情况下,先拿的人一定有办法取胜,但是他不知道对于其他情况是否有必胜策略,更不知道第一步该如何取。他决定偷偷请教聪明的你,希望你能告诉他,在给定每个瓶子中的最初豆子数后是否能让自己得到所有巧克力豆,他还希望你告诉他第一步该如何取,并且为了必胜,第一步有多少种取法?

题解

由于此题只和单个巧克力豆有关,于是此题的SG函数是关于豆子本身的。想清楚这点就好做了,令 \(SG(i)\) 代表位置 i 处一颗豆子的SG值,\(n^3\) 枚举转移。
至于输出字典序最小的方案,找第一个使得对方SG值为0的方案即可。
(话说虽然SG值不会很大,但是没有人证枚举的上界啊)

#include<bits/stdc++.h>
using namespace std;
inline int rd(){
	int f=1,j=0;
	char w=getchar();
	while(!isdigit(w)){
		if(w=='-')f=-1;
		w=getchar();
	}
	while(isdigit(w)){
		j=j*10+w-'0';
		w=getchar();
	}
	return f*j;
}
const int N=30;
int n,sg[N],sum[N],vis[N*100];
signed main(){
	for(int i=2;i<=21;i++){
		for(int j=i-1;j>=1;j--){
			for(int k=j;k>=1;k--){
				vis[sg[j]^sg[k]]=i;
			}
			for(sg[i]=0;vis[sg[i]]==i;sg[i]++);
		}
	}
	int T=rd();
	while(T--){
		n=rd();
		for(int i=1;i<=n;i++)sum[i]=rd()%2;
		int ans=0,cnt=0;
		for(int i=1;i<n;i++)if(sum[i])ans=ans^sg[n-i+1];
		if(ans==0){
			printf("-1 -1 -1\n0\n");
			continue;
		}
		int a=-1,b=0,c=0;
		for(int i=n;i>=1;i--){
			for(int j=i-1;j>=1;j--){
				for(int k=j;k>=1;k--){
					if((ans^sg[i]^sg[j]^sg[k])==0){
						if(a==-1)a=n-i,b=n-j,c=n-k;
						cnt++;
					}
				}
			}
		}
		printf("%d %d %d\n%d\n",a,b,c,cnt);
	}
	return 0;
}

标签:P3185,豆子,巧克力,int,题解,--,HNOI2007,SG,sg
From: https://www.cnblogs.com/flywatre/p/17360212.html

相关文章

  • 【题解】P4363 [九省联考 2018] 一双木棋 chess
    原题链接题目描述菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束。落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且这个格子的左侧及上方的所有格子内都有棋......
  • BUAACTF2023 Writeup题解 by Joooook
    BUAACTF2023WriteupbyJoooook目录MiscWhichElementchatgptzhuzhuzhuzhu'srevengeScreenshotcarzymazeMCCryptoBlockCipherMathKeyExchangeWebmotaReverseoneQuiz'srevenge*SnakeMinesweepobfu可以从队名猜一下博主是哪里人(nooffline......
  • 【题解】XX Open Cup, GP of Moscow
    //createdon23.03.26目录A.AliceandBobB.BracketsC.CirclesD.DejaVuE.EasiestSumF.FunnySalesmanG.GraphColoringH.HiddenGraphI.InsectsJ.JoiningPointsA.AliceandBob对于链上的情况,异色点是一定不会选择走进同色段的(长度不小于\(2\)),因为一定不优。......
  • springboot入门时,发现Java版本与Spring boot版本无法对应导致错误的问题解决
    <?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/......
  • Hackpack 2023 逆向Re部分题解
    Hackpack2023-2023/4/15https://ctf2023.hackpack.club/challenges做了2题出来,其实是一题,第一题是手动逆向,第二题是脚本自动逆向主要是学习到了nclib包使用使用说明https://nclib.readthedocs.io/en/latest/netcat.htmlSpeed-Rev题目是在3分钟逆向6题第一题是直接找字符......
  • leetcode-350-两个数组的交集 II 题解
    题目给定两个数组,编写一个函数来计算它们的交集。示例1:输入:nums1=[1,2,2,1],nums2=[2,2]输出:[2,2]示例2:输入:nums1=[4,9,5],nums2=[9,4,9,8,4]输出:[4,9]说明:输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。我们可以不考虑输出结果......
  • 2022CCPC威海站 铜牌题解 A C D E G I J 补题
    A//木桶效应#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=2e5+10;map<string,int>cham;pair<string,int>player[N];intcnt1[6];intcnt2[6];intn,m;intsum;signedmain(){cin>>n;f......
  • JOISC2016 题解
    仍然是没有做通信题。JOISC2016Day1Matryoshka俄罗斯套娃转化错了,转化成上升子序列了,然后就变成了区间LIS。实际上是LDS,那么就可以直接做了。https://qoj.ac/submission/99648JOISC2016Day1Memory2神经衰弱我们对数进行两两配对,然后把每一对都问出来。如果不存在相......
  • GLIBCXX_3.4.20 not found 问题解决【Unable to load shared library 'lib**.so'】
    前因:问题:在调用别人的so时,出现了如下问题【GLIBCXX_3.4.20notfound】Unabletoloadsharedlibrary'libdbc.so'oroneofitsdependencies.Inordertohelpdiagnoseloadingproblems,considersettingtheLD_DEBUGenvironmentvariable:/lib64/libstdc++.so.6:v......
  • ABC267G Increasing K Times 题解
    做这道题,很有感悟,发篇文。先给数列从小到大排个序。接下来设\(f_{i,j}\)表示前\(i\)个数的排列形成\(j\)个上坡的方案数。接下来考虑转移,分为插入第\(i\)个数后增加上坡和不增加上坡两种情况。对于不增加的情况,有三种可能:第\(i\)个数插入在了数列的最前端,有\(1\)......