[高精度]SCOI2019:跳跃游戏

本文深入探讨了传送门游戏中的算法解决方案,通过分析游戏模式,采用汉诺塔类似方法,推导出小球运动路径的数学公式。文章详细介绍了如何通过高精度计算找到游戏中的连续区间,以及如何运用特定的数学技巧解决复杂的游戏问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

打表找规律可以发现答案是一段一段连续的区间
用类似于汉诺塔的方法可以推出小球i的通项公式
具体的,第一个球的答案为不为3的倍数的数
第二个球的答案为为3的倍数的数但不为9的倍数的数
第二个球的答案为为9的倍数的数但不为27的倍数的数
类推下去,高精度算个答案就完了

Code:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
	int res=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
	while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
	return res*f;
}
struct gj{
	int n;
	int a[505];
	gj(){n=0;memset(a,0,sizeof(a));}
	inline gj operator + (const gj x)const{
		gj res;res.n=max(n,x.n);
		for(int i=1;i<=res.n;i++){
			res.a[i]+=x.a[i]+a[i];
			if(res.a[i]>=10) res.a[i]-=10,res.a[i+1]++;
		}
		if(res.a[res.n+1]) res.n++;
		return res;
	}
	inline gj operator / (const ll &b)const{
		ll ans=0;gj res;res.n=n;
		for(int i=res.n;i;i--){
			ans=ans*10+a[i];
			if(ans>=b) res.a[i]=ans/b,ans-=(ans/b)*b;
		}
		while(res.n && !res.a[res.n]) res.n--;
		return res;
	}
	inline int operator %(const ll &b){
		ll res=0;
		for(int i=n;i;i--){
			res=(res<<1)+(res<<3)+a[i];
			if(res>=b) res-=(res/b)*b;
		}
		return res;
	}
	inline void read(){
		char ch=getchar();
		while(!isdigit(ch)) ch=getchar();
		while(isdigit(ch)) a[++n]=ch^48,ch=getchar();
		reverse(a+1,a+n+1);
	}
}l;
ll f[31],mod;
int main(){
	int n=read(),m=read(),k=read(),q=read();
	f[1]=1,f[2]=2,mod=3*n-3;
	for(int i=3;i<=30;i++) f[i]=f[i-1]*3ll;
	l.n=1;l.a[1]=1;
	while(q--){
		gj p;p.read();
		ll res=p%mod;
		p=p/mod,p=p+p,p=p+p;
		if(res>0) p=p+l;
		if(res>n-1) p=p+l;
		if(res>n-1+k-1) p=p+l;
		if(res>n-1+k-1+n-1) p=p+l;
		for(int i=1;i<=29;i++) if(p%f[i+1]!=0) {cout<<i<<'\n';break;}
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值