[题解]LGR-180 Div.3 B&C

两道趣题。

(抽象的是\(C\)是原题,HDU2147,巴什博弈)

T2 ChS

赛时思路

一开始想的是用排列组合做,但是发现表示状态太麻烦,所以就想到做减法。

\(fac\)表示总个数\(26^n\);用\(c1\)表示一个\(ab\)都没有的个数\(24^n\);用\(c2\)表示至少包含一个\(a\)的个数\(fac-25^n\)(即\(总数-一个a没有的\))。

偶然发现有点容斥的味道,答案就是\(c1-2*c2-fac\)

题解思路

先写出总个数:\(26^n\)

然后,\(a\)\(b\)都不包含的个数:\(24^n\)

再表示出没有\(a\)和没有\(b\)的个数:都是\(25^n\)

也是容斥,答案为\(26^n-2*25^n+24^n\)

注意

  • 别忘取模。
  • long long
  • 需要注意的是,做了减法运算可能得出负数,而负数再取模会发生问题,所以可以用以下方法解决:
    • 赛时:手写一下\(mod\),使取模的结果非负(调了我半天呜呜呜)。
    • 题解:直接加一个\(mod\)再模,因为考虑最坏情况\(0-998244352=-998244352\),所以加一个就能保证非负了(题解加了\(10*mod\),一样的效果,但别加太多,小心超long long)。

Code

赛时Code
#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int T,n;
int qpow(int base,int power){
	int fac=1;
	while(power){
		if(power&1) fac=fac*base%mod;
		base=base*base%mod;
		power>>=1;
	}
	return fac;
}
int mo(int A,int B){
	int t=A%B;
	if(t<0) return t+B;
	return t;
}
signed main(){
	cin>>T;
	while(T--){
		cin>>n;
		int fac=qpow(26,n);
		int c1=qpow(24,n),c2=fac-qpow(25,n);
		//c1表示一个ab都没有,c2表示至少一个a的个数;
		cout<<mo(c1+2ll*c2%mod-fac,mod)<<endl;
	}
	return 0;
}
题解Code
#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int T,n;
int qpow(int base,int power){
	int fac=1;
	while(power){
		if(power&1) fac=fac*base%mod;
		base=base*base%mod;
		power>>=1;
	}
	return fac;
}
signed main(){
	cin>>T;
	while(T--){
		cin>>n;
		cout<<(qpow(26,n)-2*qpow(25,n)+qpow(24,n)+mod)%mod<<endl;
	}
	return 0;
}

T3 Game

题解的思路是通过暴力程序找规律(\(N,M\leq 10^{18}\)没规律也不正常),就不放了。

赛时思路

经过一番思考,得到结论:都按完美策略发挥的情况下,先碰到上或右板边的一方必胜。

为什么呢?因为碰到上或右板边,就只能轮流往一个方向走了。举个例子,现在棋子在第二行,该你走棋,那么你应当让他碰到上边,但是具体应该向上走,还是向右上走,就要看目前到右板边的距离的奇偶性了。总之知道了这个结论就可以了,我们继续。

要想让我们先到达板边,就要让到右和上的距离都为偶数。这样,对方走一步,我走一步,一定是我先抵达。就这样,我们得出了结论,第一步要让到右边和到上边的距离都为偶数。

具体实现见代码。

赛后思考

也有另一种思考方式:我们每走完一步,都要让棋子到上板边和右半边的距离都是偶数。这样,对方无论怎么走,我们都能重新调整到这个状态。最后就可以达到终点(距离都为\(0\))。

Code

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,m;
signed main(){
	cin>>t;
	while(t--){
		cin>>n>>m;
		if(n%2==1){
			if(m%2==1) cout<<"-1\n";
			else cout<<"1\n";
		}else{
			if(m%2==1) cout<<"2\n";
			else cout<<"3\n";
		}
	}
	return 0;
}
posted @ 2024-03-24 15:46  Sinktank  阅读(19)  评论(0编辑  收藏  举报
★CLICK FOR MORE INFO★ TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2024 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.