ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1375F Integer Game

2021-11-02 08:00:07  阅读:223  来源: 互联网

标签:lib stdout long Game swap CF1375F Integer fflush cases


CF1375F Integer Game
三堆石子分别有 \(a,b,c\) 个,游戏规则:

  • 先手选择一个数 \(k\)
  • 后手把他加到任意一堆石子上,但不能连续对同一堆石子操作两次
  • 如果有两堆石子数量相同,先手赢;回合数超过 \(1000\),后手赢

交互,自选先后手
\(a,b,c\le 10^9,k\le 10^{12}\)

考虑先手赢的最后一部肯定是有局面 \((n-k,n,n+k)\),并且上一步操作的是 \(n+k\),此时只要加上 \(k\) 即可
或者说存在 \(a+c=2b\) 且上一步操作的是当前最大的那一堆

考虑上一步要求操作的数是 \(p\),有局面 \((n-k,n,n+k-p)\):

  • 此时如果把 \(p\) 加到第一堆上,有 \((n-k+p,n,n+k-p)\),发现只要有 \(k<p\),就仍然可以获胜(获胜需要 \(n-k+p>n+k-p)\)
  • 此时如果把 \(p\) 加到第二堆上,有 \((n-k,n+p,n+k-p)\),发现这样不太能必胜,于是此时需要让再上一步操作必定对第二堆进行

考虑再上一步操作给出的是 \(q\),有局面 \((n-k,n-q,n+k-p)\):

  • 如果加到第一堆上,有 \((n-k+q,n-q,n+k-p)\)
    • 此时如果有 \((n-k+q)+(n+k-p)=2(n-q)\) 可以是一种必胜情况,解出此时 \(p=3q\)
    • 另有要求 \(n-k+q>n+k-p \Rightarrow 2k<p+q\Rightarrow k<\frac{2}{3}p\)
  • 如果加到第三堆上,有 \((n-k,n-q,n+k-p+q)\)
    • 此时根据之前解的 \(p=3q\),仍然是一三堆的和是二堆的两倍
    • 但需保证 \(n+k-p+q>n-k\Rightarrow k>\frac{1}{3}p\)

现在若存在合理的 \(n,k,p,q\) 并且使得上面的条件全都满足,就逐个操作 \(q,p,k\) 即可,整理出条件是:

\[\begin{cases} a=n-k\\ b=n-q\\ c=n+k-p\\ p=3q\\ k<\frac{2}{3}p\\ k>\frac{1}{3}p\\ \end{cases}\]

这样根据前面几个等式解出来就是

\[\begin{cases} n=3b-2a-c\\ q=2b-a-c\\ k=3b-2a-c\\ \end{cases}\]

此时只要钦定 \(b>c> a\),即可满足两个不等式

long long aa,bb,cc;
inline void change(int o,long long p){
	if(!o) exit(0);
	else if(o==1) aa+=p;
	else if(o==2) bb+=p;
	else if(o==3) cc+=p;
}
inline int fuck(){
	int ff=0;
	if(aa+bb==(cc<<1)) printf("%lld\n",lib::max(aa,bb)-cc),ff=1;
	else if(aa+cc==(bb<<1)) printf("%lld\n",lib::max(aa,cc)-bb),ff=1;
	else if(bb+cc==(aa<<1)) printf("%lld\n",lib::max(bb,cc)-aa),ff=1;
	if(ff) return fflush(stdout),1;
	return 0;
}
int main(){
	long long a=read(),b=read(),c=read();
	aa=a;bb=b;cc=c;
	if(a>c) lib::swap(a,c);
	if(c>b) lib::swap(b,c);
	if(a>c) lib::swap(a,c);
	if(c>b) lib::swap(b,c);
	if(a>c) lib::swap(a,c);
	if(c>b) lib::swap(b,c);
	if(a>c) lib::swap(a,c);
	if(c>b) lib::swap(b,c);
	long long n=3*b-a-c,k=3*b-2*a-c,q=2*b-a-c,p=q*3;
	puts("First");fflush(stdout);
	printf("%lld\n",q);fflush(stdout);
	change(read(),q);
	if(fuck()) return 0;
	printf("%lld\n",p);fflush(stdout);
	change(read(),p);
	if(fuck()) return 0;
	printf("%lld\n",k);fflush(stdout);
	assert(fuck());
	return 0;
}

标签:lib,stdout,long,Game,swap,CF1375F,Integer,fflush,cases
来源: https://www.cnblogs.com/suxxsfe/p/15497102.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有