【枚举找规律】记一次找规律题 埃匹希斯水晶

UPC Contest2394 - 2020年春混合个人训练第八场问题 A: 埃匹希斯水晶

题目描述
⼤家都知道,卡德加是⼀个神奇的法师。
有⼀天,他发现了⼀种可以作⽤在埃匹希斯⽔晶上的魔法:在左右两个祭坛上放⼀定量的⽔晶,然后施放⼀个法术,左边⼀堆的⽔晶数量会变成原来两个祭坛上⽔晶之和,右边⼀堆会变成两个祭坛上⽔晶数量之差。
卡德加现在有两堆⽔晶,分别有A个和B个。他打算集中精⼒连续释放N次法术,但不知道最后能拿到多少⽔晶,于是他找到了要塞指挥官(就是你了)。
输入
三个整数A,B,N(A,B≤109,N≤1018),表⽰祭坛上刚开始的⽔晶数,和法术的释放次数。
输出
两个数,祭坛上最后的⽔晶数。输出模(109+7)。
样例输入 Copy
1 2 3
样例输出 Copy
6 2

先放一个暴力代码:

while(n--)
	{
		ll tmp=a;
		a=a+b;
		b=abs(tmp-b);
		cout<<a<<" "<<b<<endl;
	}

在这里插入图片描述
这道题比较神奇,看着题目模拟的话,反正我是没能模拟出来,然后就打了个暴力的枚举法,随便找两个数,全都列出前十项进行了一波观察,一看,巧妙啊,果然有规律可循,注意奇偶的情况,比如说就那上图的第一个例子来说,奇数行,第一行左侧的值等于(2+3)×20,第三行左侧的值,(2+3)×21,第五行(2+3)×22,如果n是奇数,那么就可以根据上述规律推出左侧的值,,偶数的时候,也是相同的情况,只不过一开始的那个数是(2+3)+abs(2-3);接着再来找右侧值得规律,神奇的发现,规律也是一样的,也是只改变了一开始的那个基数;右侧奇数项一开始的那个数是abs(3-2),偶数项的话,一开始的那个数是(3+2)-abs(3-2);
接下来就请看代码吧:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll qpow(ll q,ll x,ll y)
{
	ll res=q;
	while(y)
	{
		if(y%2!=0)
		{
			res=res*x%mod;
			y--;
		}
		x=x*x%mod;
		y/=2;
	}
	return res;
 } 
int main()
{
	ll a,b,n;
	ll ans1=0,ans2=0;
	scanf("%lld%lld%lld",&a,&b,&n);
	
	ll tmp1=a+b+(abs(a-b));//偶数情况 
	//计算左侧的值 
	if(n&1)
	{
		ll cnt=n/2+1;//第几个奇数 
		ans1=qpow(a+b,2,cnt-1);
	} 
	else
	{
		ll cnt=n/2;//第几个偶数 
		ans1=ans1=qpow(tmp1,2,cnt-1);
	}
	//计算右侧的值 
	if(n&1)//奇数 
	{
		ll cnt=n/2+1;
		ans2=qpow(abs(a-b),2,cnt-1);
	}
	else//偶数 
	{
		ll cnt=n/2;
		ans2=qpow(abs(a+b-abs(a-b)),2,cnt-1);
	} 
	printf("%lld %lld\n",ans1,ans2);
	return 0;
}
/*
while(n--)
	{
		ll tmp=a;
		a=a+b;
		b=abs(tmp-b);
		cout<<a<<" "<<b<<endl;
	}
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值