首页 > 其他分享 >[POI2004] Gra

[POI2004] Gra

时间:2023-10-12 11:23:12浏览次数:45  
标签:ch int POI2004 void TP 阶梯 len Gra

前言:

谁知道我是怎么看教练的 bug 代码 AC 而怀疑人生的。已经研究困了。

思路:

题目传送门

博弈论最重要的是,发现模型并进行转模。这题很容易发现,与阶梯模型十分相似。可以考虑每个棋子距离 \(M\) 还有多少空格转化成当前在第几级阶梯。可是当我们转化后发现,胜利条件有一些不一样。阶梯模型是所有硬币到最后一级就算胜利,但在这里我们只需要有一枚硬币到最后一级就可以胜利。

起初我就是在这里卡住的。所以想到晚上睡觉的时候才想出来(不要晚上想题,会睡不着)。我们可以再往前推几步。以下推理均在对方操作时。

有一枚硬币到 \(M\) 格即为胜利,等价于有一枚硬币到 \(M-1\) 格即为失败,也就等价与所有硬币距离 \(M\) 只差两个空格时即为胜利。

请读者自己思考这段话,非常重要

这样,我们就可以转模了。设每个棋子距离 \(M-2\) 还有多少空格为在第几级阶梯上即可。第零级的可以无视,因为博弈中两人只会在无法移动其他阶梯时才会移动(下一步对手就赢了)。转模后棋子有可能在负一级,这时需要特判,直接走就赢了。

但是阶梯求方案数并不是直接像 nim 游戏的石子堆一样。在判断是否能胜利时确实只有奇数阶有贡献,但算方案时,偶数阶也可能有贡献。偶数阶可能的贡献来源相当于在原有的石子堆中多加了一堆或者是增加其中一堆的石子,从而达到平衡态,而奇数阶的贡献来源则是拿掉其中一堆的部分或全部石子来达到平衡态。

理清思路后就可以开始 coding 了。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define TP template<typename T>
#define TP_ template<typename T,typename ... T_>
TP void read(T &x)
{
	x=0;int f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
	x*=f;
}
TP_ void read(T &x,T_&...y){read(x);read(y...);}
TP void write(T x){if(x<0){putchar('-'),x=-x;}if(x>9)write(x/10);putchar(48+x%10);}
TP void writeln(const T x){write(x);puts("");}
TP void writesp(const T x){write(x);putchar(' ');}
TP_ void writeln(const T x,T_ ...y){writesp(x);writeln(y...);}
using LL=long long;
constexpr int N=1e6+5;
int n,m,a[N],c[N],f[N];
int main()
{
	read(m,n);
	for(int i=1;i<=n;i++)
		read(a[i]);
	for(int i=1;i<=n;i++)//转模
		a[i]=m-2-a[i]-n+i;
	int len=0,ones=0;
	for(int i=n;i>=1;i--)
	{
		if(a[i]==-1)
		{
			ones++;
			continue;
		}
		else if(a[i])
		{
			if(f[len]!=a[i])
				f[++len]=a[i],c[len]=1;
			else 
				c[len]++;
		}
	}
	if(ones){writeln(ones);return 0;}//1的特判
	int res=0,ans=0;
	for(int i=1;i<=len;i++)
		if(f[i]&1)
			res^=c[i];
	if(!res){puts("0");return 0;}
	for(int i=1;i<=len;i++)
	{
		if(f[i]&1)//减少其中一堆
		{
			if((res^c[i])<=c[i])
				ans++;
		}
		else
			if(f[i]-1!=f[i-1])//新加一堆
			{
				if(c[i]>=res)
					ans++;
			}
			else//增加其中一堆
			{
				int s=(res^c[i-1])-c[i-1];
				if(s>0&&s<=c[i])
					ans++;
			}
	}
	writeln(ans);
	return 0;
}

标签:ch,int,POI2004,void,TP,阶梯,len,Gra
From: https://www.cnblogs.com/lofty2007/p/17756457.html

相关文章

  • Graph Laplacian for Semi-Supervised Learning
    目录概符号说明Graph-LaplacianforSSLStreicherO.andGilboaG.Graphlaplacianforsemi-supervisedlearning.arXivpreprintarXiv:2301.04956,2023.概标题取得有一点大,其实是一个很小的点.符号说明\(X=\{x_i\}_{i=1}^n\subset\mathbb{R}^n\),asetof......
  • .net 关于在program中使用AddNewtonsoftJson之后,继承于System.Text.Json.Serializatio
    首先,先说遇见的问题与代码示例,在.net代码中注册了如下代码.AddNewtonsoftJson(option=>{//使用本地时区option.SerializerSettings.DateTimeZoneHandling=DateTimeZoneHandling.Local;......
  • 关于微信小程序VM22:2 (in promise) MiniProgramError {“errMsg“:“hideLoading:fai
    参考地址:https://blog.csdn.net/qq_41227106/article/details/108465104 出现错误的原因如下1、是微信小程序2、把请求接口统一封装,开始请求接口时showLoading,请求接口后hideLoading3、一个页面同时请求多个接口,由于请求是异步的,很有可能上一个开启了showLoading还没请求完......
  • Atcoder Grand Contest 016 E - Poor Turkeys
    先思考这样一个问题:对于一只火鸡\(i\),我们应该如何判断它最后是否能活下来。如果我们正着判断,我们其实并没有足够的证据表明每一次操作我们应该保留哪只火鸡,也就没法判断最终的答案。但是如果我们倒着考虑,我们发现,如果最后一次操作的两个火鸡都不是\(i\),那么这次操作选啥对答案......
  • 【Azure Developer】示例: 在中国区调用MSGraph SDK通过User principal name获取到Use
    问题描述示例调用MSGraphSDK通过Userprincipalname获取到User信息,如ObjectID。 参考资料选择MicrosoftGraph身份验证提供程序: https://learn.microsoft.com/zh-cn/graph/sdks/choose-authentication-providers?tabs=java#using-a-client-secret-2MicrosoftGraphSDKfor......
  • Programming abstractions in C阅读笔记:p176-p178
    《ProgrammingAbstractionsInC》学习第59天,p176-p178总结。一、技术总结1.addtivesequencestn=tn-1+tn-2序列:3,7,10,17,27,44,71,115,186,301,487,788,1275,...p177,Asageneralclass,thesequencesthatfollowthispatternarecalledadditivesequen......
  • Programming abstractions in C阅读笔记:p176-p178
    《ProgrammingAbstractionsInC》学习第59天,p176-p178总结。一、技术总结1.addtivesequencestn=tn-1+tn-2序列:3,7,10,17,27,44,71,115,186,301,487,788,1275,...p177,Asageneralclass,thesequencesthatfollowthispatternarecalledadditive......
  • 5.Program
    publicclassHelloWorld{publicstaticvoidmain(String[]args){//psvm//单行注释//输出一个Hello,World!System.out.println("Hello,World!");//sout//有趣的代码注释//多行注释:可注释一段文字/*注释*//*......
  • Graph RAG: 知识图谱结合 LLM 的检索增强
    本文为大家揭示NebulaGraph率先提出的GraphRAG方法,这种结合知识图谱、图数据库作为大模型结合私有知识系统的最新技术栈,是LLM+系列的第三篇,加上之前的图上下文学习、Text2Cypher这两篇文章,目前NebulaGraph+LLM相关的文章一共有3篇。GraphRAG在第一篇关于上下文......
  • 2021-2022 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2021) gym 104670
    原题容易想到最短路DAG求出来,起初我以为要求最小割,但这是错误的,因为可能有多条边联通了一个点的情况,这时候选择最小割不一定是最优的我们猜想一个思路:答案一定是包含\(1\)号节点的连通块全部填\(N\),剩下的填\(S\)。发现在最短路DAG中,\(1\rightarrown\)的所有路径......